我有一个需要很多依赖的类-用我的话来说,很多依赖是8或更多。它在IDE中看起来很丑陋,因为它会断行,并且在一种情况下,我有3行构造函数签名:
第一步
public class FooClass
{
public FooClass(IDependency1 dependency1, IDependency2 dependency2, ..., IDependency8 dependency8, IDependency9 dependency9)
{
...
}
...
}
我决定停止使用这种方法,并创建了依赖字典。我取得了什么?美丽的构造函数签名,但更容易获得运行时异常。
第二步
public class FooClass2
{
private IDictionary<Type, object> dependencyDictionary;
public FooClass2(IDictionary<Type, object> dependencyDictionary)
{
this.dependencyDictionary = dependencyDictionary;
...
}
...
public T GetObject<T>()
{
return (T)this.dependecyDictionary.FirstOrDefault(t => t.Key == typeof(T));
}
// USAGE
public void FooMethod()
{
IDependency1 = this.GetObject<IDependency1>();
...
}
}
但是这种类型的注册现在很丑。作为example,我使用的是AutoFac,但其他任何依赖项容器也具有相同的行为。
var builder = new ContainerBuilder();
builder.Register(c => new FooClass2(new Dictionary<Type, object>{
{typeof(IDependency1), c.Resolve<IDependency1>()},
{typeof(IDependency2), c.Resolve<IDependency2>()},
...
{typeof(IDependency8), c.Resolve<IDependency8>()},
{typeof(IDependency9), c.Resolve<IDependency9>()},
})).As<FooClass2>();
当然,为了避免使用第二种方法,我可以创建模型,模板或随意调用它,但是它会生成许多其他类,这些类仅用于指定依赖项。
第三步
public class FooDependencyDefinition
{
public FooDependencyDefinition(IDependency1 dependency1, IDependency2 dependency2, ..., IDependency8 dependency8, IDependency9 dependency9)
{
this.dependency1 = dependency1;
...
}
public IDependency1 dependency1;
public IDependency2 dependency2;
public IDependency1 dependency1;
public IDependency2 dependency2;
...
public IDependency8 dependency8;
public IDependency9 dependency9;
}
public class FooClass
{
public FooClass(FooDependencyDefinition dependencyDefinition)
{
...
}
}
我知道可以通过属性进行注入,但是我想避免这种情况。上面3种方法中的哪一种被认为是好的做法?您是否知道其他将大量依赖项传递给类的方法?
很明显,您的Step1不好,因为它有太多的依赖项。我们需要其他方法。
我强烈不鼓励您执行第二步。因为使用依赖注入的想法是使您的依赖对开发人员显而易见。使用您的方法,您很难对api进行推理。
第3步只是骇客。它负责任地将其推入采用丑陋构造函数的其他类。也不要推荐它。
确定班级的职责,将其重构为遵循单一职责原则。这样您的课程就不需要太多的依赖项。
Mark Seemann在该主题Refactoring to Aggregate Services上有出色的文章。