我正试着开始使用Unity,但我的股票在一点上。
我有一个Context类和一个Repository类正在被容器解析。我的Repository类接受上下文ctor参数作为依赖项。
我的配置文件:
容器:
<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实例,并且旧的实例已经发布。
请参见:
using (IGeneralContext context = container.Resolve<IGeneralContext>()) //NEW CONTEXT INSTANCE
{
IClienteRepository rep = container.Resolve<IClienteRepository>(); // USE DEPENDENCY AS SINGLETON
Cliente nc = new Cliente() { };
rep.Add(nc);
context.CommitChanges();
} // DISPOSE CONTEXT
using (IGeneralContext context = container.Resolve<IGeneralContext>()) //BRAND NEW CONTEXT INSTANCE
{
IClienteRepository rep = container.Resolve<IClienteRepository>(); // USE DEPENDENCY AS SINGLETON
Cliente nc = new Cliente() { };
rep.Add(nc);
context.CommitChanges();
} // DISPOSE CONTEXT
IClienteRepository rep1 = container.Resolve<IClienteRepository>(); // NEW CONTEXT AGAIN
Cliente cliente1= rep1.GetById(1);
你知道怎么用Unity解决这个问题吗?
Tks。
发布于 2010-11-16 22:46:53
在分析了更好的James建议后,我找到了一个很好的替代方案。
有一种新方法可以将实例化委托给工厂:
container.RegisterType<IMyInterface, MyConcrete>(new InjectionFactory(c => MyFactoryClass.GetInstance()));
也可以扩展配置文件来为您做这件事。
参见CodePlex上的ctavares帖子,他/她有一个非常好的例子。http://unity.codeplex.com/Thread/View.aspx?ThreadId=219565
发布于 2010-11-14 05:31:32
看一下StaticFactory扩展。您可以提供自己的对象创建方法,该方法允许您检测现有上下文是否仍然可用。
发布于 2010-11-14 08:55:30
你可能想退后一步,看看你的设计。我发现,大多数时候,我认为我需要一些复杂的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;
}
}
2)尝试将存储库作为上下文的一部分:
using (var context = container.Resolve<IGeneralContext>())
{
var nc = new Cliente() { };
context.Clientes.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();
}
}
您可能还希望尽量减少对容器的调用量。尝试通过构造函数注入尽可能多的内容。
关于工作单元模式(= Here is an interesting SO question )和可能有帮助的存储库的上下文。
我希望这能帮到你。
https://stackoverflow.com/questions/4174780
复制相似问题