Interfaces and correct use of injection in C #

I have an interface "IUser" and a class "User" that implements "IUser". Also I have an interface for the "IUserRepository" repository.

I'm in between these two options:

public interface IUserRepository
{
    List<User> getAll();
    void addUser(User user);
    void alterUser(User user);
    void deleteUser(string ID);
    bool validateLogin(string session_user, string session_pass);
    User getUserByID(int ID);
    User getUserByNombre(string name);
    User getUserBySessionUser(string session_user);
}

      

and this one

public interface IUserRepository
{
    List<IUser> getAll();
    void addUser(IUser user);
    void alterUser(IUser user);
    void deleteUser(string ID);
    bool validateLogin(string session_user, string session_pass);
    IUser getUserByID(int ID);
    IUser getUserByNombre(string name);
    IUser getUserBySessionUser(string session_user);
}

      

Here is my confusion. Should my methods on the repository interface return real implementations or interfaces? as you can see in my first option, I am returning User instances. What should I return to loosely link the code?

But if I choose the second one in my real implementation of the user repository, I only have access to the methods and properties that I declared in my IUser interface.

for example, if I call the addUser method from a service, passing it an instance of the User class:

   myRepositoryImplementation.addUser(UserInstance);

      

then i will like the real repository

  private readonly IUser user;
  public void addUser(IUser _user)
  {
    this.user=_user;
  }

      

Good sign! but then I will only have access to the method and properties declared originally in the IUser interface, not any new methods or properties declared in my User instance.

also if i call getUserByID method i get IUser instance.

So to resume this

1). Are these valid approaches?
2). If these are valid approaches, which one should I use to keep or keep the code decoupling?
3). If I choose the second option, if it is valid, should I declare in the interface everything that I will use later? I mean properties and methods?
3). Think?

+3


source to share


3 answers


1) yes, both are valid

3) yes, properties and methods

2) a slightly longer story. In short, if you have POCO classes and you're 100% sure you're never going to code a structure that doesn't allow POCOs (for example, instead, it insists on classes inheriting a base class based on the framework) you can go with the first option (classes).

But that doesn't always work.



For example coding your repos for Linq2SQL and other repos for Entity Framework Code You can't use the same set of classes at first. The second (interface) approach is the only option. We have used it successfully in several enterprise applications with no problem.

A word of advice - if you go with an interface you definitely need a method to create an empty instance

public interface IUserRepository
{
    List<IUser> getAll();
    ...
    IUser CreateNew();
}

      

Otherwise, the repository client has no other means to instantiate a particular type — the type is unknown to the client. However, some people tend to move the create method into a separate factory class.

+2


source


I would choose the first option. Having an interface for a service class like a repository is helpful, but not much for an entity class like User.

As you said, every time you add a property, you also need to add the property to the interface, which is tedious. Assuming your custom class is a simple class with no dependencies with other classes, it's easy to test even without an interface.

Related reading:



http://lostechies.com/jamesgregory/2009/05/09/entity-interface-anti-pattern/

Interfaces on objects are anti-pattern - James Gregory's blog

Should entities implement interfaces?

+2


source


I think part of your confusion is that you have methods in your User class. Typically, these types of model classes only represent data and do not describe behavior. So, if you move your methods somewhere more appropriate, all your confusion will go away because there will be no reason for an interface.

In other words, move the methods out of the User class and execute your repo:

List<User> getAll();

      

+1


source







All Articles