MEF 和实例创建的动态决策
这可能是一个奇怪的情况,但我有时想在使用 MEF 导出时重用相同的实例,有时创建一个新的实例。
基本上我有一个 WCF 服务类,它是每次调用的实例。每个实例都会导入一个 RepositoryFactory,它也将是每个服务类的新实例。我在工厂中返回一个存储库,并且存储库注入了 IDbContext。
我希望 Factory 的每个实例都注入相同的 IDbContext 实例,但 Factory 实例之间有单独的实例。
所以:
1) Factory1 is created
2) Factory1 creates Repository1-1 that gets IDbContext1 injected
3) Factory1 creates Repository1-2 that gets IDbContext1 injected
4) Factory2 is created
5) Factory2 creates Repository2-1 that gets IDbContext2 injected
6) Factory2 creates Repository2-2 that gets IDbContext2 injected
这应该确保从同一工厂创建的存储库共享一个工作单元。
但作为 MEF 的新手,我不确定我会如何去做。
编辑
这就是我得到的:
public class RepositoryFactory
{
private readonly CompositionContainer _container;
[Import(RequiredCreationPolicy=CreationPolicy.NonShared)]
private readonly IDbContext _context;
public IRepository<T> CreateRepository<T>() where T : class, IEntity
{
//Somehow add the _context instance into the Repository import
return _container.GetExportedValue<EntityRepository<T>>();
}
}
然后
public class EntityRepository<T> : IRepository<T> where T : class, IEntity
{
// Perhaps a contract name might help!!
[Import(RequiredCreationPolicy=CreationPolicy.Shared)]
protected readonly IDbContext _context;
This might be a strange case but I want to sometimes reuse the same instance when getting exports with MEF and sometimes create a new.
Basicly I have a WCF service class the is instance per call. Each instance imports a RepositoryFactory which will also be new instance per service class. I return a Repository in the Factory and a repository gets a IDbContext injected.
I want each instance of the Factory to inject the same instance of IDbContext but have seperate instances between Factory instances.
So:
1) Factory1 is created
2) Factory1 creates Repository1-1 that gets IDbContext1 injected
3) Factory1 creates Repository1-2 that gets IDbContext1 injected
4) Factory2 is created
5) Factory2 creates Repository2-1 that gets IDbContext2 injected
6) Factory2 creates Repository2-2 that gets IDbContext2 injected
This should ensures that Repositories created from the same factory share a Unit of Work.
But being new to MEF I'm not sure how I would go about doing that.
EDIT
This is what I got:
public class RepositoryFactory
{
private readonly CompositionContainer _container;
[Import(RequiredCreationPolicy=CreationPolicy.NonShared)]
private readonly IDbContext _context;
public IRepository<T> CreateRepository<T>() where T : class, IEntity
{
//Somehow add the _context instance into the Repository import
return _container.GetExportedValue<EntityRepository<T>>();
}
}
and then
public class EntityRepository<T> : IRepository<T> where T : class, IEntity
{
// Perhaps a contract name might help!!
[Import(RequiredCreationPolicy=CreationPolicy.Shared)]
protected readonly IDbContext _context;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用 MEF 无法完成此任务;无论您做什么,MEF 容器都不会正确地充当您的工作单元管理器,它不是为此而设计的。
您应该尝试显式地编写工作单元基础设施以供 DAL 使用。您的存储库应明确要求工作单元经理提供当前的工作单元及其适当的上下文。
看一下 NCommon 中的代码https://github.com/riteshrao/ncommon;您可以重构工作单元功能来满足您的需求。
You cannot accomplish this with MEF; no matter what you do the MEF container will not act correctly as a Unit of Work manager for you, it just isn't made for this.
You should attempt to explicitly code a Unit of Work infrastructure for your DAL to consume. Your repositories should explicitly ask the a Unit of Work Manager to provide a current Unit of Work and with it the appropriate context.
Take a look at the code in NCommon https://github.com/riteshrao/ncommon; you can refactor the Unit of Work features to serve your needs.
好的,这是我想出的解决方案,但还没有尝试过。它有点简单,实际上可以在 MEF 周围工作,但并没有真正破坏它,至少在我的情况下不是。
将以下方法添加到 IRepository 类:
或者更好的
是在工厂中:
其余的应该是不言自明的:
如果您以与我相同的方式使用它,我真的看不到这个实现的问题。工厂负责创建类,因此它可以负责设置上下文。 CreationPolicy 应确保每个 Factory 获取其自己的 DbContext 实例,然后将其委托给其存储库,以便它们共享上下文。
OK here is a solution I came up with but haven't tried. It's somewhat simple and actually works around MEF but doesn't really break it, at least not in my case.
Add to IRepository class the following method:
or better yet
and in the factory:
And the rest should be self explanatory:
If you are using it in the same way as I am I can't really see a problem with this implementation. The factory is responsible for creating the class so It can be responsible for setting the context. The CreationPolicy should ensure that each Factory gets it's own instance of DbContext that it then relegates to it's Repositories so they share a context.