我想不允许在以下代码中直接创建对象:
var p = new Product();
原因是我希望它由IOC控制,因此我可以轻松地更改其实现或扩展它。因此,代码看起来像:
var p = iocContainer.Get<Product>();
问题在于,人们可以“忘记”致电IOC,而不是new
产品。我的想法是让Product
成为abstract
课程。然后,动态创建一个从ProductImpl
扩展的类型Product
,这不是抽象的。在应用程序启动时,将扫描所有数据对象,并自动创建这些动态类。这可能吗?理想情况下,此类型的命名空间始终相同,例如BusinessLogic.Impl.ProductImpl
。
创建的动态类与下面的类似:
public class ProductImpl : Product
{
public ProductImpl()
{
}
}
答案 0 :(得分:1)
通常使用IOC,您应该使用接口而不是具体对象。然后,当需要接口实现时,IOC容器会创建适当的对象。
传递IProduct
接口。如果您担心人们会新建它,IOC可以随意调用实现对象。如果你真的很担心,你甚至可以把它们放在一个带内部构造函数的独立程序集中。
答案 1 :(得分:0)
使用私有构造函数而不是抽象类。
许多IoC容器支持此功能(或可以扩展到)。此外,Activator.CreateInstance
具有允许使用非公共构造函数创建对象的重载。
答案 2 :(得分:0)
您可以将构造函数设为私有,并通过反射实例化该类(请参阅this answer)。 或者,您可以使用接口及其实现来实现您描述的模式 - 我认为它比使用抽象类更好
public interface IProduct {...}
public class ProductImpl : IProduct {...}
然后使用IoC实例化实现类,但返回接口。在这种情况下,缺点是你必须记住始终使用界面而不是类。
另外,我认为根据您使用的IoC框架,可以使用私有构造函数实例化类。
更优雅的解决方案是将实现类移动到解决方案中的单独项目,并将构造函数声明为internal
。我在一个项目中使用了这种方法,使用Unity作为IoC框架。我在几个月前发布的question中描述了它的架构,以及一些你可以重新编写并用于你的案例的代码。