c# – 由MEF容器处理组件?
我使用MEF将接口映射到实现类作为DI的一种方式.例如,我使用导入属性作为接口,导出为实现类.我的理解是,MEF框架将创建实现类实例并将它们保存在MEF的容器中以供使用或自动注入.
我的一些实现类实现了IDispose接口.由于实例是由MEF创建的,我想我应该让MEF调用组件的Dispose方法,如果它们在MEF出来时是一次性的.例如,在我的申请中,我提到了MEF的容器.当应用程序终止时,我调用该容器的Dispose方法.问题是我的组件的Dispose从不被调用. 以下是有关导入和导出映射的示例代码: [Import] private IMyInterface IComponent1 { get; set; } .... [Export] private IMyInterface Component { get { var instance = new MyImplemetation(); .... return instance; } } .... 对于其他映射也有很多其他的导入和导出定义.我以这种方式构建映射,以便MEF了解关系以及如何创建映射实例的方式.以下是我的应用程序中使用AssemblyCatalog加载映射的一些代码: var catalog = new AggregateCatalog(); catalog.Add (new AssemblyCatalog(Assembly.GetExecutingAssembly()); var batch = new CompositionBatch(); batch.AddPart(catalog); // MEF container has all the mappings var container = new CompositionContainer(catalog); .... // Get instance from container var instance = container.GetExportedValue<IMyInterface>(); // my instance CTOR has a contructor with several other // implementation instances injected by interface // instance starts to do its job and coordinates others ... instance.Start(); .... // Finally the job is done. // Dispose the container explicitly there. container.Dispose(); // But my components are never disposed // this results some connections not being closed // file streams not being closed... 这里的实例有许多其他组件通过CTOR通过MEF注入.这些组件还包含由MEF注入的其他组件.问题在于,由于某些实例被共享,因此很难决定何时配置组件.如果我打电话给Dispose,这将导致其他人无法使用它.如图所示,实例由MEF创建并注入到我的应用程序类中.每个组件不应该有其他知识,应该使用注入组件来完成这项工作. 我不知道在应用程序终止或容器处理时,我应该如何指示MEF在组件上调用Dispose?我应该在组件上调用Dispose吗?我认为这是正确的,因为MEF创建它们并将其注入客户端.客户在完成工作时不应该打电话给他们. 解决方法
MEF管理其创建的组件的使用寿命.看起来您的示例中的问题是您要处理的对象实际上不是由MEF创建的.也许你想做这样的事情:
public class ComponentExporter : IDisposable { private IMyInterface _component; [Export] public IMyInterface Component { get { if (_component != null) { _component = new MyImplementation(); // ... } return _component; } } public void Dispose() { if (_component != null) { _component.Dispose(); } } } ComponentExporter是由MEF实际创建的类,如果它实现了IDisposable,则MEF将使用该容器进行处理.在此示例中,ComponentExporter在处理时处理已创建的组件,这很可能是您想要的. 当然,如果您直接将导出导出到MyImplementation类,那将会更容易.我假设你有一些理由不这样做,但这是它的外观: [Export(typeof(IMyInterface))] public class MyImplementation : IMyInterface,IDisposable { // ... } 关于代码的其他一些注意事项:您可能不需要通过批处理将目录添加到容器中,除非您将其导入到某个位置并从容器内的部分进行修改.而且,如果您正在处理许多请求并且关心性能,那么您只应该创建一次AssemblyCatalog,然后对所有请求使用相同的请求. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |