【问题标题】:Instantiating a class dynamically c#动态实例化一个类c#
【发布时间】:2012-06-05 03:15:10
【问题描述】:

我正在开发 ASP.Net MVC 中的即插即用框架,借此我可以将模块定义为独立于主项目的项目。因此,开发人员可以根据需要创建任意数量的模块。

我需要的是能够更新任何此类模块的设置。为此,在主项目中,我为一些常用设置定义了一个基类,并且每个模块都有自己的自定义设置。当对模块进行任何编辑时,我必须在主项目中实例化该模块的实例。但是,主项目不知道任何模块。

我如何做到这一点?

谢谢!

【问题讨论】:

  • 你对反射有多熟悉?
  • 这听起来像是一个像 unity 或 spring.net(依赖注入)这样的框架的工作

标签: c# asp.net-mvc-3


【解决方案1】:

您可以使用依赖注入并将这些模块注入到您的应用程序的组合根目录中。根据配置,您可以使用代码或 xml(配置文件)。您可以根据您的实际需要进行自动接线、后期绑定等。

您还可以在每个模块中使用初始化程序,因此每当您注册一个模块时,它应该初始化您注册的模块并注入依赖项等。

【讨论】:

  • 你能提供一个示例链接吗?现在任何 IOC 示例都应该没问题。一旦我有了一个想法,我总是可以根据我将使用的 IOC 进行更改。
【解决方案2】:

根据您的需要,您必须创建一个依赖于接口的解决方案。

本质上,应用程序公开了一个 API dll,其接口名为 IModule。 IModule 有一种称为 Run() 的方法。您的主应用程序将加载模块的程序集,查找实现 IModule 的东西,创建其中一个对象并在其上调用 Run()。

这是一篇旧文章,描述了如何托管沙箱以在其中运行模块。 http://msdn.microsoft.com/en-us/magazine/cc163701.aspx

namespace MyApplication.Api 
{
    public interface IModule
    { 
       void Run();
    }
}

开发者会创建类似这样的东西

public class MyObject : MarshalByRefObject, IModule
{
    public void Run()
    {
        // do something here    
    }
}

应用程序将使用某种反射加载它。

public void LoadModule()
{
     var asm = System.Reflection.Assembly.Load(/* Get the developer module name from somewhere*/);
     var types = asm.GetExportedTypes();
     foreach(var t in types)
     {
         foreach(var i = t.GetInterfaces())
         {
             if(i == typeof(IModule))
             {
                 var iModule = System.Activator.CreateInstance(t);
                 iModule.Run();
             }
         }
     }
}

最好在另一个 appDomain 中运行代码,但这会增加很多复杂性。

public void LoadModuleInAppDomain()
{
    // Spin up a new AppDomain

    // Load the assembly into the app domain

    // Get the object

    // Call the Run Method

}

【讨论】:

  • 感谢您的解决方案。但是,它部分解决了我的问题。我仍然不确定主项目将如何将对象传递给 Run(),以便每个模块都可以对对象值采取适当的操作(如更新 DB 中的值等)?
猜你喜欢
  • 1970-01-01
  • 2016-11-16
  • 2017-06-09
  • 2014-01-26
  • 2019-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多