简体   繁体   中英

Understanding TDD and Interface Properties

I am trying to understand TDD more and all the examples I have seen regarding DI have been classes/interfaces that only have methods on them eg.

public interface IUserRepository
{
   User GetByID(int ID);
}

public class UserRepo : IUserRepository
{
   private IUserRepository Repo;

   public UserRepo(IUserRepository repo)
   {
      this.Repo. = repo;
   }
   public User GetByID(int ID) {}
}

.....

private void SetupDI()
{
   container.Register<IUserRepository>.With(UserRepository);
}

I recently started writing an interface with properties on it and stopped as was unsure how this would be accomplished.

Is having properties in interfaces OK in terms of DI? Is it good design?

I would assume that these properties would be injected like so:

private void SetupDI()
{
   var myStringProp = GetPropValue("MyStringProp");
   var myIntProp = GetPropValue("MyIntProp");

   container.Register<IUserRepository>.With
             (
               new UserRepository() {
                 StringProperty = myStringProp;
                 IntProperty = myIntProp;
               }
             );
}

OR

Would you pass all the required properties in the constructor:

private void SetupDI()
{
   var myStringProp = GetPropValue("MyStringProp");
   var myIntProp = GetPropValue("MyIntProp");

   container.Register<IUserRepository>.With
             (
               new UserRepository(myStringProp,myIntProp)
             );
}

It's perfectly fine to use properties in interfaces, but your question is really mainly about constructor vs. property injection and not so much about using properties in interfaces.

The former (constructor injection) is clearly preferred since the dependencies of a class must be passed in at the time of creation, so they are clearly visible and not "hidden". Personally I aim to always use constructor injection, and property injection only as a last resort, eg when there is a cyclic dependency that otherwise cannot be resolved (at that time it is probably better to rethink the design).

I personally inject dependencies into the constructor and store them as private members. often, i will find myself with two constructors, one default that is most commonly used by the application, and one that takes the dependencies as parameters. I have found this helps me in unit testing but also gives me the flexibility.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM