具有动态加载程序集的灵活报告系统
我想为我的应用程序构建一个灵活的报告系统。 到目前为止,我脑子里只有一个概念,需要一些实施技巧。 我正在使用 Crystal Reports 来呈现报告,并且我知道如何动态加载报告。
现在的想法是每个报告都将打包为单独的程序集 (.dll)。 报告框架将加载每个自定义报告并通过明确定义的接口与其进行通信,如下所示:
public interface IReport
{
string GetTitle();
string GetDescription();
void SetParameter();
void Print();
}
此外,还会有一些基本实现(作为抽象类)来处理报告上的一些常见操作(例如绑定到数据源等):
public abstract class Report
{
...
}
每个 dll 内都会有一个具体类的实现,代表这个或那个报告:
public class CustomersReport : Report
{
...
}
现在,我必须弄清楚以下问题:
1)如何动态定位和加载dll?
2)如何创建具体类(CustomerReport)的实例并将其转换为IReport以便调用其必要的方法?
您曾经实现过这样的可扩展系统吗? 您能分享您的专业知识/代码片段吗?
提前致谢。
编辑:
在调查这个问题时,我发现 Jon Skeet 的文章 插件和强制转换异常 这可能会有所帮助。
I want to build a flexible reporting system for my application. So far I only have a concept in my head and need some tips on implementation. I'm using Crystal Reports to render reports and I know how to load reports dynamically.
Now, the idea is that every report will be packaged as a separate assembly (.dll). The reporting framework will be loading every custom report and communicating with it via clearly defined interface like this:
public interface IReport
{
string GetTitle();
string GetDescription();
void SetParameter();
void Print();
}
Also, there will be some base implementation (as an abstract class) that will handle some common operations on the reports (like binding to data source, etc.):
public abstract class Report
{
...
}
Inside every dll there will be an implementation of concrete class, representing this or that report:
public class CustomersReport : Report
{
...
}
Now, I have to figure out the following:
1) How to dynamically locate and load the dll?
2) How to create an instance of concrete class (CustomerReport) and cast it to IReport in order to call necessary methods on it?
Have you ever implemented such an extensible system? Could you please share your expertise / code snippets?
Thanks in advance.
EDIT:
While investigating this question I found Jon Skeet's article on Plug-ins and Cast Exceptions that might be helpful.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
看看这个:
将 dll 动态加载到我的程序中时出现问题
就是做你想做的事,没有周围所有的 YAGNI。
See this:
Problem with dynamic loading of a dll into my program
Is doing exactly what you want wihtout all the YAGNI around it.
看看 Mono.Addins (它是 MIT 许可证,所以封闭软件也可以) 。 从你的描述来看,它满足你的需要。 基本上它使用依赖树+基于接口的插件。 它有自己的加载 .dll-s 管理器,并且它的对象基于加载的接口,因此您不需要更多的魔法铸造来调用任何东西。
Have a look at Mono.Addins (it's MIT license so it's ok with closed software). From your description it does what you need. Basically it uses a dependency tree + plugins based on interfaces. It has it's own manager for loaded .dll-s and its objects are based on the loaded interface, so you don't need any more magic casting to call anything.
您可以考虑 Microsoft 的 MEF。 它是一个组合引擎,可以设置为监视本地文件夹并自动加载导出您感兴趣的部件(在您的情况下实现 IReport)的程序集。
我们确实有一个类似于我们不久前实施的系统。 我们有一个包含报告的程序集,我们将其加载到单独的应用程序域中,并在文件版本发生更改时重新加载。 然后我们使用 .NET 远程处理在应用程序域之间进行通信。 我们考虑使用 Microsoft 的插件框架,但我们发现它非常复杂且令人印象深刻,并认为它在我们的案例中过于沉重和复杂。
You can consider MEF from Microsoft. It is a composition engine that can be set up to monitor a local folder and automatically load assemblies that export parts (implementation of IReport in your case) that you're interested in.
We do have a system like that we implemented sometime ago. We have a single assembly with reports that we load into a separate application domain and reload if the file version has changed. Then we use .NET remoting to communicate between app domains. We considered using Add-in framework from Microsoft but we found it to be very complex and imposing and decided it was too heavy and complex in our case.