我有一个业务逻辑操作的基类,由我的同事继承。此类公开一个构造函数,该构造函数需要objectContext
作为参数。您可以将此基类视为原子CRUD操作的组件(其所有选择,插入,编辑和删除方法将始终仅作用于一个实体)。
然后,我有一个“超类”,其主要目的是在所有上述基类之间共享objectContext
以执行某些业务事务,并且它必须提供任何baseClass
实例,如果需要的话。
所以,我正在寻找优雅的方式将superClass的objectContext
“注入”baseclass
:
public BaseClass<T> where T : entity
{
private ObjectContext _ctx;
public BaseClass(ObjectContext ctx){ _ctx = ctx;}
public virtual IList<T> Select(){..}
public cirtual voind Insert(T entity){..}
// other stuff
}
public class SuperClass
{
private ObjectContext _ctx = new...
public BaseClass<TEntity> LoadBaseClass(TBase, TEntity) where TBase : BaseClass<TEntity>, where TEntity : class
{
BaseClass<TEntity> obj = Activator.CreateInstance(typeof(TBase), _ctx); // share objectContext
}
public int SaveAll(){return _ctx.SaveChanges();}
}
正如您所看到的,我的超类能够通过其类型返回一些baseClass
实例,这正是我想要的。但是,如果某个继承类使用其他参数定义自己的构造函数,则LoadBaseClass
方法将失败。
我会找到一个干净的解决方案,以避免在LoadBaseClass
方法的实例创建过程中出现任何错误。我知道的唯一方法是定义一个私有的构造函数,但是通过这种方式,没有人能够继承baseclass
..
答案 0 :(得分:2)
您要找的是Dependency Injection。您现在正在尝试手动构建它,但有很多工具已经做了您想要的工作。
依赖注入就是构建对象并配置创建这些对象的方式和时间。它归结为从业务逻辑中分离对象创建。
在您的情况下,您正在处理名为Unit Of Work和Repository模式的内容。使用像Ninject这样的依赖注入容器,您可以轻松配置要在所有存储库之间共享的UnitOfWork
,如下所示:
var kernel = new StandardKernel();
kernel.Bind<IMyRepository>().To<ConcreteRepository();
kernel.Bind<IMyUnitOfWork>().To<ObjectContextImp>().InRequestScope();
IMyRepository repos = kernel.Get<IMyRepository>();
Ninject(或任何DI工具)将尝试构建IMyRepository
。您已将其配置为查找ConcreteRepository
。然后它注意到ConcreteRepository
在其构造函数中使用IMyUnitOfWork
。在这种情况下,您已将其映射到ObjectContextIml
并添加了InRequestScope
选项。
InRequestScope
适用于ASP.NET Web应用程序,这意味着应为每个请求创建一次上下文。 Ninject有几个不同的Object Scopes,可用于配置如何创建和共享对象。
这样,您就可以完全控制对象的创建方式。