首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >单喷射器的中介模式与对比分析

单喷射器的中介模式与对比分析
EN

Stack Overflow用户
提问于 2015-01-12 20:04:34
回答 2查看 2K关注 0票数 4

这个问题源于这样一个事实:我试图为MediatR:https://github.com/jbogard/MediatR/pull/14创建一个简单的Injector实现。

在试图解决通用处理程序接口的实现时,我遇到了麻烦。考虑以下通知处理程序接口:

代码语言:javascript
复制
public interface INotificationHandler<in TNotification>
    where TNotification : INotification
{
    void Handle(TNotification notification);
}

INotifcation只是一个空的标记接口。

我为Pinged (实现INotification)事件定义了以下处理程序:

代码语言:javascript
复制
public class PingedHandler : INotificationHandler<Pinged>
{
    public void Handle(Pinged notification) { }
}

public class PingedHandler2 : INotificationHandler<Pinged>
{
    public void Handle(Pinged notification) { }
}

还有一个通用处理程序(请注意,这应该处理每个INotification):

代码语言:javascript
复制
public class GenericHandler : INotificationHandler<INotification>
{
    public void Handle(INotification notification) { }
}

登记如下:

代码语言:javascript
复制
var container = new Container();

container.RegisterManyForOpenGeneric(
    typeof (INotificationHandler<>),
    (service, impls) => container.RegisterAll(service, impls),
    AppDomain.CurrentDomain.GetAssemblies());

现在我希望:

代码语言:javascript
复制
GetAllInstances<INotificationHandler<Pinged>>();

来解决它所做的PingedHandlerPingedHandler2。但是它没有解析GenericHandler,因为它实现了INotificationHandler<INotification>而不是INotificationHandler<Pinged>。我想知道是否有一种方法可以让简单的喷射器搜索整个对象图并解析任何属于Pinged的东西。

我从史蒂文那里找到了关于协方差和对方差的博客文章,但我无法让它适用于我的例子。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-01-13 09:49:57

tl;dr:这是简单注射器v2.6.0中的一个缺陷/缺点,它在v2.7.0中得到了修正。问题中的配置(如下所示)现在确实起作用了。

总之,@qujck的回答和@Steven的评论:我能够通过安装带有以下配置的简单Injector v2.7.0-beta2 (实际上与问题中的配置相同)来使其工作:

代码语言:javascript
复制
// Simple Injector v3.x
container.RegisterCollection(typeof(INotificationHandler<>),
    AppDomain.CurrentDomain.GetAssemblies());

// Simple Injector v2.x
container.RegisterManyForOpenGeneric(
    typeof(INotificationHandler<>),
    container.RegisterAll,
    AppDomain.CurrentDomain.GetAssemblies());

现在,简单注入器能够在请求时解析PingedHandlerPingedHandler2GenericHandler

代码语言:javascript
复制
container.GetAllInstances<INotificationHandler<Pinged>>();
票数 2
EN

Stack Overflow用户

发布于 2015-01-12 21:25:39

更新

对于简单的InjectorVersion2.7,此功能现在是标准的,您不再需要下面所示的解决方法。

您缺少了那篇文章中描述的MultipleDispatchEventHandler的一个变体。接受基本逻辑并将其应用到抽象中确实会给出您期望的结果:

代码语言:javascript
复制
[Fact]
public void RegisterAll_Contravariant_Succeeds()
{
    var container = new Container();

    container.RegisterManyForOpenGeneric(
        typeof(INotificationHandler<>),
        (service, impls) => container.RegisterAll(service, impls),
        AppDomain.CurrentDomain.GetAssemblies());

    var handlersType = typeof(IEnumerable<INotificationHandler<Pinged>>);

    var handlersCollection = (
        from r in container.GetCurrentRegistrations()
        where handlersType.IsAssignableFrom(r.ServiceType)
        select r.GetInstance())
        .Cast<IEnumerable<INotificationHandler<Pinged>>>()
        .ToArray();

    var result = 
        from handlers in handlersCollection
        from handler in handlers
        select handler;

    Assert.Equal(3, result.Count());
}

但是,使GenericHandler成为通用的可能更容易:

代码语言:javascript
复制
public class GenericHandler<TNotification> : INotificationHandler<TNotification>
    where TNotification : INotification
{
    public void Handle(TNotification notification) { }
}

进行简单的登记

代码语言:javascript
复制
[Fact]
public void RegisterAll_WithOpenAndClosedGenerics_Succeeds()
{
    var container = new Container();

    var types = OpenGenericBatchRegistrationExtensions
        .GetTypesToRegister(
            container,
            typeof(INotificationHandler<>),
            AccessibilityOption.AllTypes,
            AppDomain.CurrentDomain.GetAssemblies())
        .ToList();

    types.Add(typeof(GenericHandler<>));

    container.RegisterAll(typeof(INotificationHandler<>), types);

    var result = container.GetAllInstances<INotificationHandler<Pinged>>().ToList();

    Assert.Equal(3, result.Count());
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27909866

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档