如何在 WCF 服务中动态加载和卸载 .Net 程序集

发布于 2024-11-06 01:35:48 字数 459 浏览 4 评论 0原文

我想开发一个 Windows 服务托管的 wcf Web 服务,它将充当任务执行管理和报告服务。每个任务都将表示为 .net 程序集,任务名称和 dll 路径将位于中央配置中。该任务至少主要有一个 Execute 和一个 Stop 方法。 当wcf服务运行和其他任务运行时,应该可以加载、执行、停止和卸载任务。每个任务的一个实例可以同时运行。出现异常的一项任务不应中止其他任务。我正在思考方法,就像

[OperationContract]    
bool Load(string taskName);
[OperationContract]
bool Run(string taskName);

我正在思考如何完成按需加载和卸载任务以及隔离一样。一些选项将使用反射、MAF(System.Addin)等。加载的初始性能影响是可以接受的,因为这种加载/卸载很少发生。

实现这一目标的最佳方法是什么(库、API、框架等)。

I want to develop a windows service hosted wcf web service that would behave as a task execution management and reporting service. Each task would be represented as a .net assembly, the task name and dll path would be in a central configuration. The task would primarily have a Execute and a Stop method at the very least.
It should be possible to load, execute, stop and unload tasks while the wcf service is running and other tasks are running. One instance of each task can be running concurrently. One task having an exception should not abort other tasks. I am thinking of methods like

[OperationContract]    
bool Load(string taskName);
[OperationContract]
bool Run(string taskName);

I am thinking of how I can accomplish this loading and unloading tasks on demand as well as the isolation. Some options would be using Reflection, MAF (System.Addin) etc. The initial performance hit to load is acceptable as this load/unload would occur very infrequently.

What is the best way (library, api, framework etc) to achieve this goal.

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

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

发布评论

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

评论(2

红尘作伴 2024-11-13 01:35:48

我不能说最好的,但唯一(!)的方法涉及多个应用程序域。由于您无法卸载程序集,只能卸载应用程序域,因此属于任务的所有程序集必须加载到单独的应用程序域中。

这在技术上来说是非常简单的事情。魔鬼在于细节。 MAF 可能是一个很好的框架。

I can not say about the best, but the ONLY (!) approach involvesm ultiple appdomains. Because you can NOT unload an assembly, only an appdomain, so all assemblies belonging to a task must be loaded in a separate appdomain.

This is technically very trivial to do. The devil is in the detail. MAF may be a good framework for that.

窝囊感情。 2024-11-13 01:35:48

我只需定义每个提供的程序集必须实现的接口。

我正在开发一个实现管道行为的项目,此代码片段可能对您有所帮助:它使用 linq 搜索所有加载的程序集,以查找实现特定接口并且具有空构造函数和自定义属性的类(您可以不需要自定义属性部分) - 并且它实例化找到的每个项目的实例。

我知道这并不完全是您所追求的,但希望它能为您指明正确的方向 - 希望它有帮助:)

        var processingModules = from mod in
                                   AppDomain.CurrentDomain.GetAssemblies().SelectMany(assembly =>
                                   {

                                       return from t in assembly.GetTypes()

                                              where 
                                                    t.GetInterfaces().Contains(typeof(IProcessingModule<T>))
                                                    && t.GetConstructor(Type.EmptyTypes) != null
                                                    && t.GetCustomAttributes(typeof(ProcessModuleAttribute), true)
                                                           .Cast<ProcessModuleAttribute>()
                                                           .Select(e => e.Processes.Contains(manager.Name))
                                                           .Contains(true)

                                              select Activator.CreateInstance(t) as IProcessingModule<T>;
                                   })
                                   orderby mod.ModuleOrder
                                       select mod;

I would just define an interface which each supplied assembly must implement.

I'm working on a project that implements a pipeline behaviour, this code snippet might be helpful to you: it uses linq to search all loaded assemblies for classes that implement a particular interface and which have an empty constructor and a custom attribute (you may not need the custom attribute part) - and it instantiates an instance of each item found.

I appreciate that this isn't exactly what you're after, but hopefully it'll point you in the right direction - Hope it helps :)

        var processingModules = from mod in
                                   AppDomain.CurrentDomain.GetAssemblies().SelectMany(assembly =>
                                   {

                                       return from t in assembly.GetTypes()

                                              where 
                                                    t.GetInterfaces().Contains(typeof(IProcessingModule<T>))
                                                    && t.GetConstructor(Type.EmptyTypes) != null
                                                    && t.GetCustomAttributes(typeof(ProcessModuleAttribute), true)
                                                           .Cast<ProcessModuleAttribute>()
                                                           .Select(e => e.Processes.Contains(manager.Name))
                                                           .Contains(true)

                                              select Activator.CreateInstance(t) as IProcessingModule<T>;
                                   })
                                   orderby mod.ModuleOrder
                                       select mod;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文