Microsoft 可扩展性框架 - MEF CompositionContainer

发布于 2024-10-12 11:21:46 字数 1667 浏览 2 评论 0原文

我正在构建一个实现 MEF 的 Windows 服务。这个想法是,服务应该管理子组件并且是可插入的,可以在运行时引入任意数量的新组件,而无需经历完整的服务重新编译和部署场景。这些组件应该是可插拔的,这意味着只要我将输出程序集放入光盘上的指定文件夹中,Windows 服务就应该说“嘿,这是一个要运行的新组件...”,然后就可以了。这就是 MEF 的力量。到目前为止非常酷的东西。

我了解创建 AggregateCatalog 和 CompositionContainer 来导入所有可用子组件(程序集)的概念。这一切都很好,并且在 Windows 服务首次启动时它按预期工作。但是,我最终将在运行时引入新组件,因此在某些时候我将需要 CompositionContainer 来识别添加的任何新输出程序集。

我担心以下问题对性能的影响。将 CompositionContainer 逻辑放入如下循环中是否安全/高效:

        [ImportMany(AllowRecomposition = true)]
        private IEnumerable<Lazy<IMySubComponentTask, IDictionary<string, object>>>                        
        MySubComponentTasks { get; set; }

        while (true)
        {
          //Create a general aggregate catalog
          var catalog = new AggregateCatalog();

          //Adds all the parts found in the same assembly as the Program class
          catalog.Catalogs.Add(new AssemblyCatalog(typeof(MySubComponentTaskFactory).Assembly));

          //Create a new directory catalog
          var directoryCatalog = new DirectoryCatalog(@".\Extensions");

          //Add the DLLs in the directory to the aggregate catalog
          catalog.Catalogs.Add(directoryCatalog);

          //Create the current composition container to create the parts
          var container = new CompositionContainer(catalog);

          //Fill the imports of this object
          try
          {
            container.ComposeParts(this);
          }
          catch (CompositionException compositionException)
          {
            Console.WriteLine(compositionException.ToString());
          }
       }

任何反馈或输入都会受到赞赏。

谢谢, 麦克风

I'm in the process of building a Windows Service that implements MEF. The idea is that the service should manage sub-components and be pluggable, where any number of new components can be introduced at runtime without having to go through a full service recompile and deploy scenario. The components should be pluggable, meaning that as soon as I drop an output assembly into a designated folder on disc, the Windows Service should say "Hey, here's a new component to run..." and just do it's thing. That's the power of MEF. Very cool stuff so far.

I understand the concept of creating an AggregateCatalog and a CompositionContainer to import all available sub-components (assemblies). This is all good, and it works as expected when the Windows Service is intially started up. However, I'm eventually going to be introducing new components at runtime, so at some point I'm going to need the CompositionContainer to recognize any new output assemblies that are added.

My concern with the following is any implications on performance. Is it safe / efficient to put the CompositionContainer logic into a loop such as the following:

        [ImportMany(AllowRecomposition = true)]
        private IEnumerable<Lazy<IMySubComponentTask, IDictionary<string, object>>>                        
        MySubComponentTasks { get; set; }

        while (true)
        {
          //Create a general aggregate catalog
          var catalog = new AggregateCatalog();

          //Adds all the parts found in the same assembly as the Program class
          catalog.Catalogs.Add(new AssemblyCatalog(typeof(MySubComponentTaskFactory).Assembly));

          //Create a new directory catalog
          var directoryCatalog = new DirectoryCatalog(@".\Extensions");

          //Add the DLLs in the directory to the aggregate catalog
          catalog.Catalogs.Add(directoryCatalog);

          //Create the current composition container to create the parts
          var container = new CompositionContainer(catalog);

          //Fill the imports of this object
          try
          {
            container.ComposeParts(this);
          }
          catch (CompositionException compositionException)
          {
            Console.WriteLine(compositionException.ToString());
          }
       }

Any feedback or input is appreciated.

Thanks,
Mike

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

喵星人汪星人 2024-10-19 11:21:46

不,我不会将目录实例化放入循环中。但是,也许可以使用 System.Timers.Timer 或 System.Threading.Timer 来定期检查插件目录 - 无论哪个最适合您的需要。

由于您的 ImportMany 允许重新组合,您应该能够在运行时添加新的组合:

Timer checkPlugin = new Timer();

//set CheckForPlugins as a timer callback or action
void CheckForPlugins()
{
    // add plugins catalog if found in directory
}

我发现了一些其他信息:重组和构造函数

No, I would not put the catalog instantiation into a loop. However, maybe a System.Timers.Timer or System.Threading.Timer to periodically check the plugin directory - whichever best suits your need.

Since your ImportMany allows recomposition you should be able to add new compositions at runtime:

Timer checkPlugin = new Timer();

//set CheckForPlugins as a timer callback or action
void CheckForPlugins()
{
    // add plugins catalog if found in directory
}

I found some additional information: Recomposition and constructors

药祭#氼 2024-10-19 11:21:46

创建 CompositionContainer 应该很便宜。创建目录并不便宜,因为必须检查组件才能找到 MEF 零件。因此,如果可能的话,您应该在循环之外创建目录。

Creating CompositionContainers should be cheap. Creating catalogs is not so cheap because the assemblies have to be inspected to find MEF parts. So you should create your catalog outside of the loop if possible.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文