gpt4 book ai didi

c# - CompositionContainer.SatisfyImportsOnce 是否重用组件?

转载 作者:行者123 更新时间:2023-11-30 22:35:05 24 4
gpt4 key购买 nike

在 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 目录中搜索导出。

然后,我设置了一些需要导入属性的 web 服务:

它们都是这样构建的:

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 类只实例化了一次。

你能澄清一下我是否在滥用组合框架吗?

  1. 我认为在应用程序生命周期内使用一个组合容器是个好主意,我错了吗?
  2. SatisfyImportsOnce 的多次调用似乎使用相同的唯一实例填充目标。是真的吗?如果为真,我如何才能简单地更改我的代码以在每次调用该方法时拥有一个新实例?
  3. 有什么改进我的代码的建议吗?

最佳答案

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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com