最近我经常遇到这种情况,需要一个优雅的解决方案。我有:
public abstract class TypeA
{
public abstract void AbtractMethod(IDependency dependency);
}
public class TypeB : TypeA
{
public override void AbtractMethod(ISpecializedDependencyForB dependency) { }
}
public class TypeC : TypeA
{
public override void AbtractMethod(ISpecializedDependencyForC dependency) { }
}
public interface IDependency { }
public interface ISpecializedDependencyForB : IDependency { }
public interface ISpecializedDependencyForC : IDependency { }
我的目标是使客户端的视角更加透明,以便像这样使用代码:
TypeA myDomainObject = database.TypeARepository.GetById(id); // The important point here is that I don't know if the object is of TypeB or TypeC when I consume it.
IDependency dependency = ? // How do I get the right dependency
myDomainObject.AbtractMethod(dependency);
因为我不知道对象的具体类型,所以无法向其注入正确的依赖项。目前我的解决方法是创建一个抽象工厂来注入正确的属性。但这种方式会有两个问题:一是会有很多工厂;二是它使得多态性变得无用,因为客户端实际上需要关心“管理”基础类型(我需要在工厂中注入所有可能的依赖项,并在客户端代码中实例化工厂)。
因此,我考虑使用Unity进行属性注入,但我无法确定是否可以在手动实例化对象后解析其依赖项。即使采用这种方法,我认为仍然会遇到同样的问题:如果存在以下语法,则无法确定Unity是否会检查对象的实际类型并解析正确的依赖项:
unityContainer.Resolve<TypeA>(myDomainObject)
如果没有的话,我需要事先了解类型,并且会回到同样的问题。
2) 我找到了这篇文章提到 EF 提供了一些 DI 机制,但似乎只是用于注入框架服务(PluralizationService 等)。否则,这将是一个很好的方式来实现。
3) 在这种情况下,我也可以不使用 DI...看起来 DI 的概念与多态性不太匹配。虽然我对这个想法并不感到兴奋。
我很乐意为我正在尝试实现的属性注入找到解决方案,或者一个我可以使用的模式的想法。但是,我真的不想为此目的创建一个大型基础设施并使我的代码混乱不堪。
注意:在这种情况下,我不想使用领域事件。
谢谢