根据枚举值从 IoC 容器解析
问题
我有一个带有 MessageType
字段的 protobuf 消息定义,它是一个枚举。给定传入的 protobuf 消息,我想根据 MessageType
从 IoC 容器解析一些 IMessageHandler
。问题是双重的:在编写 IMessageHandler
时如何表达 MessageType
约束,以及如何从 IoC 容器中仅解析所需的处理程序?
我正在使用 Autofac,但对任何容器的听力解决方案都很感兴趣。
我的想法:
为了表达约束,我看到两个选项:属性或属性(不能使用泛型,因为它是枚举值)。我喜欢这个属性,因为它使得在不指定约束的情况下无法编写 IMessageHandler
,但缺点是必须先实例化它,然后才能看到属性值。
在我当前的代码中,我使用的是属性方法。我解析了所有 IMessageHandler
并手动进行过滤,但似乎应该有更好的方法。并不是说我太担心性能,只是感觉我正在解决不被使用的实例。
更新
为了让它更清楚一点,这就是我现在正在做的事情
public interface IMessageHandler
{
MessageType TargetType { get; }
void Handle(IMessage message);
}
public class SomeHandler : IMessageHandler
{
public MessageType TargetType
{
get { return MessageType.Type1; }
}
public void Handle(IMessage message)
{
// implementation
}
}
所以当我收到 protobuf 消息时,我解析所有 IMessageHandler
并调用其 TargetType
与传入消息的MessageType
匹配。
Problem
I have a protobuf message definition with a MessageType
field, which is an enum. Given an incoming protobuf message, I would like to resolve some IMessageHandler
s from an IoC container based on the MessageType
. The problem is twofold: How do I express the MessageType
constraint when writing an IMessageHandler
, and how do I resolve only the desired handlers from the IoC container?
I'm using Autofac but am interested in hearing solutions for any container.
My thoughts:
For expressing the constraint, I see two options: a property or an attribute (can't use generics because it is an enum value). I like the property because it makes it impossible to write an IMessageHandler
without specifying the constraint, but the downside is that it has to be instantiated before you can see the property value.
In my current code, I'm using the property approach. I resolve all IMessageHandler
s and do the filtering manually, but it seems like there should be a better way. Not that I'm too worried about performance, it just kind of smells that I'm resolving instances that don't get used.
Update
To make it a little more clear, here's what I'm doing now
public interface IMessageHandler
{
MessageType TargetType { get; }
void Handle(IMessage message);
}
public class SomeHandler : IMessageHandler
{
public MessageType TargetType
{
get { return MessageType.Type1; }
}
public void Handle(IMessage message)
{
// implementation
}
}
So when I receive a protobuf message, I resolve all IMessageHandler
s and invoke the ones whose TargetType
matches the MessageType
of the incoming message.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我建议您使用 autofac 注册一个 IMessageHandler-Factory 类,并在该工厂上实现一个方法,该方法接受您的枚举并返回正确的 IMessageHandler 实现。
I suggest you register a single IMessageHandler-Factory class with autofac and implement a method on that factory that takes your enum and returns the right IMessageHandler implementation.
我意识到 Autofac 的密钥服务可以帮助我。我想我会采用这种方法。
IMessageHandler
感兴趣的MessageType
MessageType
键控的IMessageHandler
ResolveKeyed
仅获取我感兴趣的IMessageHandler
。好处是,如果有人忘记使用该属性,我们可以在构建容器时捕获它。这是一个完整的例子。任何建议都是非常受欢迎的!
I realized that Autofac's Keyed Services can help me out. I think I'm going to go with this approach.
MessageType
a givenIMessageHandler
is interested in.IMessageHandler
keyed to theMessageType
ResolveKeyed
to get only theIMessageHandler
s I'm interested int.The nice thing is if someone forgets to use the attribute, we can catch it while building the container. Here's a full example. Any suggestions are most welcome!