我使用以下语法创建了一个对象:
var newMessage = Activator.CreateInstance(client.Key);
它似乎创建了一个正确类型的对象,并允许设置对象属性。但是,当我将对象传递给具有签名的方法时:
public void Publish<T>(T messageBody)
T定义的Type是object。
我如何解决这个问题?我无法更改方法签名 - 它来自库 - 我需要能够在运行时创建对象而不事先知道它们的类型。
已更新
我尝试执行的功能与发送(发布)消息有关。通常我会注册一个消息处理程序,如:
RegisterHandler<MyMessage> (m => do something with message );
然后可以打电话
Publish<MyMessage> (message)
最终会在处理程序中结束。这很酷,工作正常。
我要做的是插入一个中介作为交换,并将消息发布给多个处理程序。我知道还有其他一些东西可以用来为我做这件事,比如RabbitMQ,但我希望能够通过对当前代码进行一些小修改来实现它。
所以我有一个注册订阅的方法:
public virtual void registerSubscription<T1,T2>()
{
if (handlerMap.ContainsKey(typeof(T2)))
{
throw new ArgumentException("Message handler has already been registered for type: " +typeof(T2).Name);
}
if (!handlerMap.ContainsValue(typeof(T1)))
{
mqHost.RegisterHandler<T1> (m => distributeMessage(m) );
}
handlerMap[typeof(T2)] = typeof(T1);
}
我用两个类调用该方法,一个基类和一个继承基类的类:
public class MyMessage
{
public string name {get;set;}
}
public class MyMessage2:MyMessage{}
这个位运行良好,我得到了一个处理器的地图。当我执行下一位,即distributeMessage方法时会出现问题。
var match = handlerMap.Where(i => i.Value == message.Body.GetType());
foreach (var client in match)
{
var newMessage = Activator.CreateInstance(client.Key);
newMessage.PopulateWith(message.Body);
messageProducer.Publish(createMessage(newMessage));
}
messageProducer.publish具有签名:
public void Publish<T>(T messageBody)
我不能(轻松)修改它 - 它是库的一部分。还有另一种方法我可以打电话:
public void Publish<T>(IMessage<T> message)
但我看不出这会更容易,因为我必须创建一个仍然需要的消息。
答案 0 :(得分:4)
您可以使用一些反射来尝试创建一个发布的通用方法,给出您在调用Activator时知道的类型信息。如果我误解了你想要做的事情,请询问我可以修改这段代码。
object newObject = Activator.CreateInstance(myType);
var publishMethod = typeof(MessageProducer).GetMethod("Publish");
var publishMethodWithCorrectType = publishMethod.MakeGenericMethod(new Type[] { myType });
publishMethodWithCorrectType.Invoke(messageProducer, new object[]{newObject});
我希望这会有所帮助。
答案 1 :(得分:1)
尝试这样做:
var newMessage = (MyType)Activator.CreateInstance(client.Key);
P.S。 MyType是基本类型或接口......
答案 2 :(得分:0)
您还需要通过反射调用Publish<T>
方法以继续沿着此路线。
另一个建议是根据class
类型使client.Key
对象的类通用,然后在该类中实现Publish方法 - 实现将知道T
是什么。 / p>
答案 3 :(得分:0)
发现此answer到另一个问题
并实施了这个:
typeof(MessageExchange)
.GetMethod("createMessage",BindingFlags.Static | BindingFlags.NonPublic)
.MakeGenericMethod(newMessage.GetType())
.Invoke(null, new object[] { newMessage });
我现在正在通过正确的类型。