c# - 激活器.CreateInstance : Dynamic Instantiation of Classes

标签 c# factory-pattern activator

我正在设计一个松耦合的结构。我想通过由字符串表示的代码从不同的程序集/命名空间调用类。我的设计是,每个客户端的业务规则都位于不同的程序集上,并且彼此不依赖(一个客户端与一个 DLL 的比例),这样当我对 1 个客户端的业务规则进行更新时,不会影响其他客户端。我现在的注意力是使用 Factory Design 和使用 Activator.CreateInstance() 方法。

这是项目设置(2+n DLL)

 namespace Foundation; // where the interfaces/abstract resides
 namespace Factory; // has dependency on Foundation assembly
 namespace Client1; // client1's DLL, no dependency
 namespace Client2; // client2's DLL, no dependency
 The UI // only referenced to the Foundation and Factory not the Clients

实际代码

 namespace Foundation
 {
   public interface IBusinessRules
   {
     string GetBusinessRule();
  }
 }

 namespace Client1 //DLL for client 1
 {
   public class BusinessRules : Foundation.IBusinessRules
   {
    public string GetBusinessRule()
    {
        return "Client1 Business Rule";
    }
   }
}

namespace Client2 //DLL for client 2
{
   public class BusinessRules : Foundation.IBusinessRules
   {
     public string GetBusinessRule()
     {
        return "Client2 Business Rule";
     }
   }
}


namespace Factory
{
  public static class Invoker<T> where T: Foundation.IBusinessRules
  {
    public static T FetchInstance(string clientCode) 
    {
        return (T)Activator.CreateInstance(Type.GetType(clientCode));   
    }
  }
}


 //sample implementation that generates unhandled Exception
 using Factory;
 using Foundation;
 static void Main(string[] args)
 {
      //the parameter is maintained in the database
       IBusinessRules objClient1 = Invoker<IBusinessRules>.FetchInstance("Client1"); 

       //should call Client1.BusinessRules method
        Console.WriteLine(objClient.GetBusinessRule());  
        Console.Read();

        objClient = Invoker<IBusinessRules>.FetchInstance("Client2");

        //should call Client2.BusinessRules method
        Console.WriteLine(objClient.GetBusinessRule()); 
        Console.Read();      
  }

知道为什么我的示例不起作用吗?有什么改进设计的建议吗? 提前致谢。

如何使用

Expression.Lambda

有人吗?

最佳答案

如果您使用 FetchInstance("Client.BusinessRules"),则您的代码可以工作,前提是所有内容都在同一个程序集中。如果不是(根据您的设计),您需要给出 AssemblyQualifiedName .

不过我会以不同的方式进行设计。保留仅使用“Client1”作为参数的调用,但更改工厂的实现。动态加载给定客户端的程序集(使用 Assembly.Load() 或 Assembly.LoadFrom()),然后使用 clientAssembly.CreateInstance() 实例化您的类型。

编辑:原始代码示例:

namespace Factory
{
  public static class Invoker<T> where T: IBusinessRules
  {
    public static T FetchInstance(string clientCode)
    {
        var clientAssembly = Assembly.LoadFrom(clientCode + ".dll");

        return (T)clientAssembly.CreateInstance(clientCode+".BusinessRules");
    }
  }
}

如果您不知道 client-dll 中的类名,则必须搜索适用的类型,例如使用 clientAssembly.GetTypes()。

关于c# - 激活器.CreateInstance : Dynamic Instantiation of Classes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3727433/

相关文章:

c# - 在 WPF 中解析本地 XML 文档(调试工作,发布后失败)

C# 实时 try catch

java - 工厂类的 create() 方法应该是静态的吗?或者制作工厂类单例?

android - 如何在 Android 中实现 ViewModel 工厂

c# - 静态类的克隆

c# - 在 asp.net C# 中重定向按钮单击上的新选项卡(Response.Redirect)

c# - 如何使用反射设置类型为 List<CustomClass> 的属性

java - 将属性传递给工厂方法

c# - 使用已编译的 Lambda 表达式而不是 Activator.CreateInstance 来初始化 SoapHttpClientProtocol 对象

c# - 如何检查某个程序集是否存在?