如何将类型与另一个程序集中的工厂例程配对

本文关键字:集中 工厂 例程 程序集 程序 类型 另一个 | 更新日期: 2023-09-27 18:35:02

我正在尝试在我的程序中创建一个通用例程,它将为我实例化对象。实际负责调用新 Object(( 的例程位于必须实例化的工厂中的不同程序集中。

namespace ExternalLib
{
    class Object1Factory
    {
        public Object1 getObject1()
            //...
    }
    class Object2Factory
        // Same implementation as Object1Factory
}

正在尝试为我的应用程序提供一个例程,该例程将允许我调用适当的例程来为我"新建"对象。

namespace MyApp
{
    class Program
    {
        static void Main()
            //...
        static Object getNewObject(string typeName)
        {
            //This is where I have problems
        }
    }
}

我可以访问外部库和程序的源代码,尽管完全重写架构的成本太高。

我尝试过:我最初的想法是在工厂和/或工厂例程上使用自定义属性,并使用反射来获取方法,然后调用该方法。我最初使用签名private static T getNew<T>()并尝试在类型参数上使用 switch 语句,但意识到getNewObject(string typeName)会更容易。工厂具有相同的构造函数签名,但没有继承链接。

总而言之:创建对象的例程在工厂中的另一个程序集中,如何自动调用这些例程以根据类型获取对象?

如何将类型与另一个程序集中的工厂例程配对

如果你想

继续这条路 - 你能把所有的工厂方法放在一个叫做'ObjectFactory'的工厂类中吗?

Type t = typeof(OtherAssembly.ObjectFactory);
MethodInfo m = t.GetMethods().Where(a => a.ReturnType.Name == typeName).FirstOrDefault();
return m.Invoke(null, new object[] { /* PARAMETERS */ });


编辑 - 回应詹姆斯对问题的评论,称他更愿意将工厂类分开:

(使用下面马丁的想法,并依赖于所有工厂类的名称为"[Type]Factory"(

(在工厂类上也有非静态方法(

Type t = Type.GetType(String.Format("OtherAssembly.{0}Factory", typeName));
var myFactory = Activator.CreateInstance( t );
MethodInfo m = t.GetMethods().Where(a => a.ReturnType.Name == typeName).FirstOrDefault();
return m.Invoke(myFactory, new object[] { /* PARAMETERS */ });

也许我在问题中遗漏了一些东西,但是只使用它有什么问题:

static Object getNewObject(string typeName)
{
    var type = Type.GetType(typeName);
    return Activator.CreateInstance(type);      
}

也许需要一些字符串操作和反射,如果typeName是Object1并且你想掌握Object1Factory,然后使用反射在工厂上调用getObject1((方法。

如果你可以传入typeName,比如"MyNameSpace.Object1, Object1Assembly",那么它将从相关的程序集加载它。

纯粹是为了响应您尝试的内容,如果您将签名更改为:

static T GetNew<T>() where T : new()
{
    // Then you can do this:
    return new T();
}

它在类型 T 上放置公共无参数构造函数的泛型约束。但是,这是没有意义的,因为调用代码如下所示:

var obj = GetNew<MyClass>();

而它通常看起来像这样:

var obj = new MyClass();

所以我不会把它作为一种解决方案,但它会起作用,并且会否定对 switch 语句的需求。