Dependency injection 如何在每次处理旧实例时使用Unity解决新实例
我试图开始使用Unity,但我得到了一个要点 我有一个上下文类和一个由容器解析的存储库类。 我的存储库类将上下文参数作为依赖项 我的配置文件: 容器:Dependency injection 如何在每次处理旧实例时使用Unity解决新实例,dependency-injection,unity-container,ioc-container,Dependency Injection,Unity Container,Ioc Container,我试图开始使用Unity,但我得到了一个要点 我有一个上下文类和一个由容器解析的存储库类。 我的存储库类将上下文参数作为依赖项 我的配置文件: 容器: <register type="IGeneralContext" mapTo="Data.EF.EFContext, Data.EF"> <lifetime type="singleton" /> <constructor> <param name="connection
<register type="IGeneralContext" mapTo="Data.EF.EFContext, Data.EF">
<lifetime type="singleton" />
<constructor>
<param name="connectionString">
<value value="anyConnStr"/>
</param>
</constructor>
</register>
<register type="IClienteRepository" mapTo="Repository.EF.ClientRepository, Repository.EF">
<constructor>
<param name="context">
<dependency type="Data.EF.EFContext, Data.EF"/>
</param>
</constructor>
</register>
现在,我希望在调用Resolve时构造一个新的IGeneralContext实例,而旧实例已经发布
见:
使用(IGeneralContext context=container.Resolve())//新上下文实例
{
iclienterpository rep=container.Resolve();//将依赖项用作单例
Cliente nc=新的Cliente(){};
代表添加(nc);
context.CommitChanges();
}//处置上下文
使用(IGeneralContext context=container.Resolve())//全新的上下文实例
{
iclienterpository rep=container.Resolve();//将依赖项用作单例
Cliente nc=新的Cliente(){};
代表添加(nc);
context.CommitChanges();
}//处置上下文
iclienterpository rep1=container.Resolve();//新语境
Cliente client1=rep1.GetById(1);
你知道如何用统一来解决吗
Tks 看看StaticFactory扩展。您需要提供自己的对象创建方法,该方法允许您检测现有上下文是否仍然可用
您可能想后退一步,看看您的设计。我发现,大多数时候我认为我需要一些复杂的DI配置,问题实际上在我的设计中。以下是您可以考虑的几个选项: 1) 使用工厂创建存储库并向该工厂提供上下文:
var repositoryFactory = container.Resolve<IRepositoryFactory>();
using (var context = container.Resolve<IGeneralContext>())
{
var rep = repositoryFactory.Create<IClienteRepository>(context);
// ...
}
public class RepositoryFactory : IRepositoryFactory
{
public TRepository Create<TRepository>(IGeneralContext context)
where TRepository : IRepository
{
var repository = Container.Resolve<TRepository>();
repository.Context = context;
return repository;
}
}
var repositoryFactory=container.Resolve();
使用(var context=container.Resolve())
{
var rep=repositoryFactory.Create(上下文);
// ...
}
公共类存储工厂:IRepositoryFactory
{
公共存储创建(IGeneralContext上下文)
在哪里存储:i存储
{
var repository=Container.Resolve();
Context=Context;
返回存储库;
}
}
2) 尝试使存储库成为上下文的一部分:
using (var context = container.Resolve<IGeneralContext>())
{
var nc = new Cliente() { };
context.Clientes.Add(nc);
// ...
}
使用(var context=container.Resolve())
{
var nc=新客户机(){};
context.clients.Add(nc);
// ...
}
如果无法将所有这些存储库属性都放在上下文本身上,则可能需要创建一个包装器对象:
using (var context = container.Resolve<NorthwindContext>())
{
var nc = new Cliente() { };
context.ClienteRepository.Add(nc);
// ...
}
public class NorthwindContext
{
private IGeneralContext context;
private IRepositoryFactory repFactory;
public NorthwindContext(IGeneralContext context,
IRepositoryFactory repFactory)
{
this.context = context;
this.repFactory = repFactory;
}
public IClienteRepository Clientes
{
get { return this.repFactory
.Create<IClienteRepository>(this.context); }
}
public IOrderRepository Orders
{
get { return this.repFactory
.Create<IOrderRepository>(this.context); }
}
public void CommitChanges()
{
this.context.CommitChanges();
}
}
使用(var context=container.Resolve())
{
var nc=新客户机(){};
context.clientrepository.Add(nc);
// ...
}
公共类NorthwindContext
{
私有IGeneralContext上下文;
私营电子零售工厂;
公共NorthwindContext(IGeneralContext上下文,
IRepositoryFactory(工厂)
{
this.context=上下文;
this.repFactory=repFactory;
}
公众客户
{
获取{返回此.repFactory
.Create(this.context);}
}
公共存储库订单
{
获取{返回此.repFactory
.Create(this.context);}
}
公共无效佣金()
{
this.context.CommitChanges();
}
}
您可能还希望尽量减少对容器的调用量。尝试通过构造函数注入尽可能多的内容
关于可能有用的工作单元模式(=上下文)和存储库
我希望这能有所帮助。在分析了更好的詹姆斯建议后,我找到了一个好的替代方案 有一种新方法可以将实例化委托给工厂:
container.RegisterType<IMyInterface, MyConcrete>(new InjectionFactory(c => MyFactoryClass.GetInstance()));
container.RegisterType(新注入工厂(c=>MyFactoryClass.GetInstance());
此外,还可以扩展配置文件来为您执行此操作
参见CodePlex的ctavares帖子,他/她有一个很好的例子。
Thaks Steven,这很有帮助。我使用Unity只是为了简化我的工作单元和存储库的实例化。一旦我没有其他理由这样做,我发现最好使用一个简单的工厂(没有统一性)为开发人员完成工作。如果只需要配置XML配置文件,甚至在我的设计中稍加调整,就可以了。无论如何非常感谢你!Thaks James告诉Steven,我把Unity带到了我的项目中,以简化我的设计。如果可能的话,只需配置th XML配置文件,我会发现最好继续这样做。一旦不可能,我将把这些实例化委托给工厂方法。
container.RegisterType<IMyInterface, MyConcrete>(new InjectionFactory(c => MyFactoryClass.GetInstance()));