灵活的报告系统,带动态加载的组件

时间:2022-04-05 16:02:13

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.

我想为我的应用程序构建一个灵活的报告系统。到目前为止,我只有一个概念,需要一些实施技巧。我正在使用Crystal Reports来呈现报告,我知道如何动态加载报告。

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:

现在,我们的想法是每个报告都将打包为一个单独的程序集(.dll)。报告框架将加载每个自定义报告,并通过明确定义的界面与之通信,如下所示:

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:

在每个dll中都会有一个具体类的实现,代表这个或那个报告:

public class CustomersReport : Report
{
    ...
}

Now, I have to figure out the following:

现在,我必须弄清楚以下内容:

1) How to dynamically locate and load the dll?

1)如何动态定位和加载DLL?

2) How to create an instance of concrete class (CustomerReport) and cast it to IReport in order to call necessary methods on it?

2)如何创建具体类的实例(CustomerReport)并将其强制转换为IReport以便在其上调用必要的方法?

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.

在调查这个问题的同时,我发现Jon Skeet关于插件和演员例外的文章可能会有所帮助。

3 个解决方案

#1


See this: Problem with dynamic loading of a dll into my program Is doing exactly what you want wihtout all the YAGNI around it.

看到这个:将dll动态加载到我的程序中的问题正在完成您想要的所有YAGNI周围的问题。

#2


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.

看看Mono.Addins(这是麻省理工学院的许可证,因此可以使用封闭式软件)。根据您的描述,它可以满足您的需求。基本上它使用基于接口的依赖树+插件。它有自己的加载.dll-s管理器,它的对象基于加载的接口,所以你不需要任何魔法转换来调用任何东西。

#3


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.

你可以考虑微软的MEF。它是一个组合引擎,可以设置为监视本地文件夹并自动加载导出您感兴趣的部件(在您的情况下实现IReport)的程序集。我们确实有一个类似于我们之前实现的系统。我们有一个包含报告的程序集,我们将其加载到单独的应用程序域中,并在文件版本发生更改时重新加载。然后我们使用.NET远程处理在应用程序域之间进行通信。我们考虑使用Microsoft的Add-in框架,但我们发现它非常复杂且非常复杂,并且在我们的案例中认为它过于繁重和复杂。

#1


See this: Problem with dynamic loading of a dll into my program Is doing exactly what you want wihtout all the YAGNI around it.

看到这个:将dll动态加载到我的程序中的问题正在完成您想要的所有YAGNI周围的问题。

#2


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.

看看Mono.Addins(这是麻省理工学院的许可证,因此可以使用封闭式软件)。根据您的描述,它可以满足您的需求。基本上它使用基于接口的依赖树+插件。它有自己的加载.dll-s管理器,它的对象基于加载的接口,所以你不需要任何魔法转换来调用任何东西。

#3


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.

你可以考虑微软的MEF。它是一个组合引擎,可以设置为监视本地文件夹并自动加载导出您感兴趣的部件(在您的情况下实现IReport)的程序集。我们确实有一个类似于我们之前实现的系统。我们有一个包含报告的程序集,我们将其加载到单独的应用程序域中,并在文件版本发生更改时重新加载。然后我们使用.NET远程处理在应用程序域之间进行通信。我们考虑使用Microsoft的Add-in框架,但我们发现它非常复杂且非常复杂,并且在我们的案例中认为它过于繁重和复杂。