我正在尝试在我的程序中创建一个通用例程来为我实例化对象。实际负责调用新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>()
并尝试在type参数上使用switch语句,但实现getNewObject(string typeName)
会更容易。工厂具有相同的构造函数签名,但没有继承链接。
总结:创建对象的例程在另一个程序集的工厂中,如何根据类型自动调用这些例程来获取对象?
答案 0 :(得分:4)
如果您想继续沿着这条路走下去 - 您是否可以将所有工厂方法放在一个名为'ObjectFactory'的工厂类中?
Type t = typeof(OtherAssembly.ObjectFactory);
MethodInfo m = t.GetMethods().Where(a => a.ReturnType.Name == typeName).FirstOrDefault();
return m.Invoke(null, new object[] { /* PARAMETERS */ });
编辑 - 回应詹姆斯的问题评论,表示他更愿意将工厂课程分开:
(使用Martin的想法,并依赖于所有工厂类名称“[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 */ });
答案 1 :(得分:2)
也许我在问题中遗漏了一些东西,但是使用它时出了什么问题:
static Object getNewObject(string typeName)
{
var type = Type.GetType(typeName);
return Activator.CreateInstance(type);
}
如果typeName是Object1并且您希望获得Object1Factory,然后使用反射来调用工厂上的getObject1()方法
,可能会进行一些字符串操作和反射如果您可以传入typeName作为“MyNameSpace.Object1,Object1Assembly”,那么它将从相关程序集中加载它。
答案 2 :(得分:0)
纯粹是为了回应您的尝试,如果您将签名更改为:
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语句的需要。