简体   繁体   English

如何更改实例进程的创建? (例如:DI、工厂……)

[英]How to change the creation of instance process? (ex : DI, Factory…)

During the compose process, MEF create instances of types imported using the constructor by default or the "ImportingConstructor".在撰写过程中,MEF 创建默认使用构造函数或“ImportingConstructor”导入的类型的实例。

I want to override this process of creation.我想覆盖这个创建过程。

For example:例如:

  • Use DI pattern (using Unity)使用 DI 模式(使用 Unity)

  • Use Factory pattern使用工厂模式

Is it possible to do that with MEF?可以用 MEF 做到这一点吗?

Short answer: it is possible but requires effort.简短的回答:这是可能的,但需要努力。

Longer:更长:

  • In order to provide objects for imports (exported values), MEF operates on instances of Export class.为了提供导入对象(导出值),MEF 对Export class 的实例进行操作。 The exported value is retrieved using Export.Value property.使用Export.Value属性检索导出的值。
  • If you wish to ad-hoc register particular instance of object within CompositionContainer , you may do that using AddExportedValue or ComposeExportedValue .如果您希望在CompositionContainer中临时注册 object 的特定实例,您可以使用AddExportedValueComposeExportedValue来实现。
  • If you wish to intercept the process of creation of objects by MEF, this is totally different story.如果您希望拦截 MEF 创建对象的过程,则完全不同。

We could simplify structure of MEF artifacts to:我们可以将 MEF 工件的结构简化为:

All above classes are abstract.以上所有类都是抽象的。 If you will analyze concrete classes used by MEF (eg use CompositionContainer with TypeCatalog ), you will figure out that most of the implementation is internal and there is not much chances to inject custom logic.如果您分析 MEF 使用的具体类(例如,将CompositionContainerTypeCatalog一起使用),您会发现大部分实现是内部的,注入自定义逻辑的机会并不多。 Still, there are some options.尽管如此,还是有一些选择。

You may implement proxy object for the specific, concrete MEF's type.您可以为特定的具体 MEF 类型实现代理 object。 For instance, if you need to intercept all exported values the CompositionContainer provides:例如,如果您需要拦截CompositionContainer提供的所有导出值:

Sample:样本:

public class CompositionContainerProxy : CompositionContainer
{
    protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition)
    {
        IEnumerable<Export> exports = base.GetExportsCore(definition, atomicComposition);

        List<Export> proxies = new List<Export>();
        
        foreach (Export export in exports)
        {
            proxies.Add(new ExportProxy(export, this));
        }

        return proxies;
    }

    private object Intercept(object value)
    {
        return value; // TODO: Provide intercept logic.
    }

    private class ExportProxy : Export
    {
        private readonly Export export;

        private readonly CompositionContainerProxy proxy;

        public override ExportDefinition Definition
        {
            get { return export.Definition; }
        }

        internal ExportProxy(Export export, CompositionContainerProxy proxy)
        {
            this.export = export;
            this.proxy = proxy;
        }

        protected override object GetExportedValueCore()
        {
            object value = export.Value;

            return proxy.Intercept(value);
        }
    }
}

This way you may eg assure thread safety etc. See, eg: Controller.cs这样,您可以例如确保线程安全等。参见,例如: Controller.cs

QComposite use such tricks for eg implementing hierarchical structure of controllers, export visibility scope etc. https://www.qube7.com/guides/controller-composition.html QComposite 使用这些技巧来实现控制器的层次结构、导出可见性scope等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM