2

I have an application which have two fields IP & Mac, with two checkboxes, to indicate if the user wants to check if the IP AND/OR MAC addresses he entered are unique or not . I use to do the checking inside my post action methods using service method.

But this have required to repeat the same check on my Post Create and POST Edit action emthods.so I found another way to move my validation logic from my action methods and put them inside my model Ivalidatable object as follow:-

public class ConsoleServerJoin : IValidatableObject
    {
Repository repository = new Repository();
        public ITSYSConsoleServer ConsoleServer { get; set; }

        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            if (ConsoleServer != null)
            {
bool IT360ipunique = repository.ISIT360IPUnique(NetworkInfo.IPAddress);
bool IT360macunique = repository.ISIT360MACUnique(NetworkInfo.MACAddress);
bool ITSYSipunique = repository.ISITSYSIPUnique(NetworkInfo.IPAddress);
bool ITSYSmacunique = repository.ISITSYSMACUnique(NetworkInfo.MACAddress);
                if ((IsIPUnique == true) && (!IT360ipunique || !ITSYSipunique))
                {
                    yield return new ValidationResult("Error occurred. The Same IP is already assigned.", new[] { "NetworkInfo.IPAddress" });

                }
                if ((IsMACUnique == true) && (!IT360macunique || !ITSYSmacunique))
                {
                    yield return new ValidationResult("Error occurred. The Same MAC Address is already assigned.", new[] { "NetworkInfo.MACAddress" });

                }
            }
        }

    }
}

So my question is whether calling my model repository from my Ivalidatble object a right approach to follow, or i should only be calling my repository class from inside the controller classes ?

Thanks

John John
  • 1
  • 72
  • 238
  • 501

1 Answers1

3

So my question is whether calling my model repository from my Ivalidatble object a right approach to follow, or i should only be calling my repository class from inside the controller classes ?

I would say neither. A repository should only handle data access (CRUD operations). I would recommend a middle "Services" layer that has a repository (BTW, is your repository just a copy of your Database context?) and has methods that interact with your models. This way, there is a clearer separation of concerns, making your code more testable and easier to maintain and you still won't have to duplicate the code. You can use dependency injection to inject your service into your controller and inject your repository(ies) into your service.

EDIT: Generally, you'll have either a generic repository (Repository<T>) or a repository class for each entity you work with (StudentRepository). These repositories know how to get, create, update, delete these entities. Your repository above appears to have methods that are more business layer type methods:

repository.ISIT360IPUnique(NetworkInfo.IPAddress);

These types of methods could exist in your services layer. So, controller calls service, which has a repository.

Look into repository pattern examples. Here is the contoso example. It's a good starting point.

Matt M
  • 3,699
  • 5
  • 48
  • 76
  • yes my repository handle CRUD operations and it interacts with the database. so why i should avoid calling my repository from my model class? can you explain your point in more details? – John John Jul 15 '14 at 19:02
  • 1
    @johnG I updated my answer. Hopefully, it makes more sense to you. I would recommend checking out the link. – Matt M Jul 15 '14 at 19:42
  • but in my case i have only one repository that have the CRUD operation for all the models(student , course, department, etc). and i am currently defining the validation such as ISIT360Unique inside the repository also. so in my current situation what will be the best approach to keep using single repository but remove the validation from it . as the link you provide about the Contoso university do not talk about the services layer. can u advice ? – John John Jul 15 '14 at 20:16
  • @johnG I would create a services layer that contains a class for each entity (ie NetworkInfoService) and move those methods into the service. Each service should have an instance of your repository. I can't go into more detail without a better understanding of your architecture. But, separating those methods from your repository and your model is the first step. – Matt M Jul 15 '14 at 20:24
  • so in this case my Controller will be referencing the Repository and also the Service layer class ? – John John Jul 16 '14 at 09:39
  • No, your controller only references the service. the service references the repository. – Matt M Jul 16 '14 at 11:57
  • So I injected my service in the controller, how can i access it from ValidationContext object? – blogbydev May 13 '15 at 10:34
  • Posted it here sometime back http://stackoverflow.com/questions/30213330/how-can-i-have-a-iserviceprovider-available-in-validationcontext-parameter-of-iv – blogbydev May 13 '15 at 13:36