在 WCF 服务项目中,我为 MEF CompositionContainer 创建了一个简单的包装器以简化其实例化:
internal class CompositionProxy
{
private static Lazy<CompositionContainer> m_lazyCC;
static CompositionProxy()
{
m_lazyCC = new Lazy<CompositionContainer>(() =>
{
var batch = new CompositionBatch();
var dc1 = new DirectoryCatalog(
HttpContext.Current.Server.MapPath("~/bin")
);
return new CompositionContainer(dc1);
}
);
}
public static CompositionContainer DefaultContainer
{
get
{
return m_lazyCC.Value;
}
}
}
这个想法是在应用程序生命周期内拥有一个 CompositionContainer,它在 bin 目录中搜索导出。
然后,我设置了一些网络服务,需要导入属性:
它们都是这样构建的:
public class MyService: IMyService
{
public MyService()
{
CompositionProxy.DefaultContainer.SatisfyImportsOnce(this);
}
[Import]
private IContext Context { get; set; }
public void DoTheJob()
{
// Logic goes here
}
}
在其他地方,我有一个与此导出匹配的类:
[Export(typeof(IContext))]
public class MyContext
{
public MyContext(){
Log("MyContext created");
}
}
在构造函数中,我要求组合容器填充 IContext Context
属性。
这似乎有效,在我的服务中,我可以看到 Context
属性已正确填充。
但是,我遇到了内存泄漏,并且我的跟踪显示 MyContext
类仅实例化一次。
你能澄清一下我是否误用了组合框架吗?
- 我认为在应用程序的生命周期内使用一个组合容器是个好主意,我错了吗?
- 对
SatisfyImportsOnce
的多次调用似乎使用相同的唯一实例填充目标。是真的吗?如果是这样,我如何简单地更改代码以在每次调用该方法时都有一个新实例? - 有任何改进我的代码的建议吗?
最佳答案
I supposed it's a good idea to have one composition container for the application lifetime
是的,您应该为应用程序的生命周期创建一个容器。
the multiple calls to SatisfyImportsOnce seems to populate the target with the same unique instance. Is it true ? If true, how can I simply change my code to have a new instance each time the method is called ?
您需要[Import(RequiredCreationPolicy=CreationPolicy.NonShared)]
。
Any suggestion to improve my code ?
如果可能,不要将容器公开为全局容器,并在代码中调用它。这就是服务定位器模式,与依赖注入(inject)相比,它有一些缺点。您的服务不必尝试自行组合,只需声明它需要什么即可:
[Export(typeof(IMyService))]
public class MyService: IMyService
{
private readonly IContext context;
public MyService(
[Import(typeof(IContext),
RequiredCreationPolicy=CreationPolicy.NonShared)]
IContext context)
{
if (context == null)
throw new ArgumentNullException("context");
this.context = context;
}
public void DoTheJob()
{
// Logic goes here
}
}
在 WCF 服务中,我认为您应该只需要在 ServiceHostFactory
实现中调用容器。不过我对 WCF 不太熟悉。
关于c# - CompositionContainer.SatisfyImportsOnce 是否重用组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7552483/