C# 使用带信号器的简易喷油器

C# 使用带信号器的简易喷油器,c#,signalr,simple-injector,C#,Signalr,Simple Injector,我认为使用我自己的国际奥委会对信号员来说是非常直接的,也许是这样;很可能我做错了什么。以下是我目前掌握的代码: private static void InitializeContainer(Container container) { container.Register<IMongoHelper<UserDocument>, MongoHelper<UserDocument>>(); // ... registrations like abo

我认为使用我自己的国际奥委会对信号员来说是非常直接的,也许是这样;很可能我做错了什么。以下是我目前掌握的代码:

private static void InitializeContainer(Container container)
{

   container.Register<IMongoHelper<UserDocument>, MongoHelper<UserDocument>>();
   // ... registrations like about and then:
   var resolver = new SimpleInjectorResolver(container);
   GlobalHost.DependencyResolver = resolver;
}
private static void InitializeContainer(容器)
{
container.Register();
//…注册大约,然后:
var解析器=新的SimpleInjectorResolver(容器);
GlobalHost.DependencyResolver=解析程序;
}
然后我的班级:

public class SimpleInjectorResolver : DefaultDependencyResolver
{
    private Container _container;
    public SimpleInjectorResolver(Container container)
    {
        _container = container;
    }

    public override object GetService(Type serviceType)
    {
        return _container.GetInstance(serviceType) ?? base.GetService(serviceType);
    }

    public override IEnumerable<object> GetServices(Type serviceType)
    {
        return _container.GetAllInstances(serviceType) ?? base.GetServices(serviceType);
    }
}
公共类SimpleInjectorResolver:DefaultDependencyResolver
{
私家货柜;;
公共SimpleInjectorResolver(容器)
{
_容器=容器;
}
公共重写对象GetService(类型serviceType)
{
返回_container.GetInstance(serviceType)?base.GetService(serviceType);
}
公共重写IEnumerable GetServices(类型serviceType)
{
返回_container.GetAllInstances(serviceType)??base.GetServices(serviceType);
}
}
最终发生的是,我得到一个错误,IJavaScriptProxyGenerator无法解决,因此我认为,我将添加注册:

container.Register<IJavaScriptProxyGenerator, DefaultJavaScriptProxyGenerator>(
    ConstructorSelector.MostParameters);
container.Register(
施工选择者(大多数参数);
但是还有很多其他的!我可以:

container.Register<IDependencyResolver, SimpleInjectorResolver>();
container.Register<IJavaScriptMinifier, NullJavaScriptMinifier>();
container.Register<IJavaScriptProxyGenerator, DefaultJavaScriptProxyGenerator>(
    ConstructorSelector.MostParameters);
container.Register<IHubManager, DefaultHubManager>();
container.Register<IHubActivator, DefaultHubActivator>();
container.Register<IParameterResolver, DefaultParameterResolver>();
container.Register<IMessageBus, InProcessMessageBus>(ConstructorSelector.MostParameters);
container.Register();
container.Register();
集装箱。登记(
施工选择者(大多数参数);
container.Register();
container.Register();
container.Register();
容器.寄存器(构造函数选择器.MostParameters);
这仍然让我“找不到类型
ITraceManager
的注册。”。。。但现在我想知道我做的是否正确,因为我希望我不需要重新连接信号器正在做的一切…对吗?有希望地?如果不是,我会继续跋涉,但我是一个信号员和简单的喷油器新手,所以我想我应该先问一下

附加:由于SignalR有多个构造函数。

更新此答案已针对SignalR版本1.0进行了更新

以下是如何为简单喷油器构建信号器
idependencysolver

公共密封类SimpleInjectorResolver
:Microsoft.AspNet.signal.IDependencyResolver
{
私人货柜;
私人IServiceProvider提供商;
私有DefaultDependencyResolver defaultResolver;
公共SimpleInjectorResolver(容器)
{
this.container=容器;
this.provider=容器;
this.defaultResolver=新的DefaultDependencyResolver();
}
[调试步骤至]
公共对象GetService(类型serviceType)
{
//强制创建中心实现
//通过简单的喷油器,无需无声故障。
如果(!serviceType.isastract&&typeof(IHub).IsAssignableFrom(serviceType))
{
返回此.container.GetInstance(serviceType);
}
返回此.provider.GetService(serviceType)??
this.defaultResolver.GetService(serviceType);
}
[调试步骤至]
公共IEnumerable GetServices(类型serviceType)
{
返回此.container.GetAllInstances(serviceType);
}
公共无效寄存器(类型serviceType,IEnumerable activators)
{
抛出新的NotSupportedException();
}
公共无效寄存器(类型serviceType,Func activator)
{
抛出新的NotSupportedException();
}
公共空间处置()
{
这个.defaultResolver.Dispose();
}
}
不幸的是,
DefaultDependencyResolver
的设计存在问题。这就是为什么上面的实现不是继承自它,而是包装它。我在SignalR网站上发布了一个关于此的问题。你可以读到它。尽管设计师同意我的观点,但不幸的是,1.0版中还没有解决这个问题


我希望这能有所帮助。

以下几点对我很有用。此外,在实例化依赖项解析器之前,您需要在中心类的容器中注册一个委托

ex: container.Register<MyHub>(() =>
        {
            IMyInterface dependency = container.GetInstance<IMyInterface>();

            return new MyHub(dependency);
        });

public class SignalRDependencyResolver : DefaultDependencyResolver
{
    private Container _container;
    private HashSet<Type> _types = new HashSet<Type>();

    public SignalRDependencyResolver(Container container)
    {
        _container = container;

        RegisterContainerTypes(_container);
    }

    private void RegisterContainerTypes(Container container)
    {
        InstanceProducer[] producers = container.GetCurrentRegistrations();

        foreach (InstanceProducer producer in producers)
        {
            if (producer.ServiceType.IsAbstract || producer.ServiceType.IsInterface)
                continue;

            if (!_types.Contains(producer.ServiceType))
            {
                _types.Add(producer.ServiceType);
            }
        }
    }

    public override object GetService(Type serviceType)
    {
        return _types.Contains(serviceType) ? _container.GetInstance(serviceType) : base.GetService(serviceType);
    }

    public override IEnumerable<object> GetServices(Type serviceType)
    {
        return _types.Contains(serviceType) ? _container.GetAllInstances(serviceType) : base.GetServices(serviceType);
    }
}
ex:container.Register(()=>
{
IMyInterface dependency=container.GetInstance();
返回新的MyHub(依赖项);
});
公共类SignalDependencyResolver:DefaultDependencyResolver
{
私家货柜;;
私有HashSet_types=新HashSet();
公共信号依赖解析程序(容器)
{
_容器=容器;
RegisterContainerTypes(_容器);
}
专用无效注册表容器类型(容器)
{
InstanceProducer[]producer=container.GetCurrentRegistrations();
foreach(生产者中的InstanceProducer生产者)
{
if(producer.ServiceType.isastract | | producer.ServiceType.IsInterface)
继续;
if(!\u types.Contains(producer.ServiceType))
{
_添加(producer.ServiceType);
}
}
}
公共重写对象GetService(类型serviceType)
{
返回\u types.Contains(serviceType)?\u container.GetInstance(serviceType):base.GetService(serviceType);
}
公共重写IEnumerable GetServices(类型serviceType)
{
返回_types.Contains(serviceType)_container.GetAllInstances(serviceType):base.GetServices(serviceType);
}
}

嗯,我昨天试过了,我找到了解决办法。 据我所说,我唯一想在信号器中注入依赖项的时刻是为了我的集线器:我不关心信号器内部是如何工作的! 因此,我没有替换DependencyResolver,而是创建了自己的iHubaActivator实现:

public class SimpleInjectorHubActivator : IHubActivator
{
    private readonly Container _container;

    public SimpleInjectorHubActivator(Container container)
    {
        _container = container;
    }

    public IHub Create(HubDescriptor descriptor)
    {
        return (IHub)_container.GetInstance(descriptor.HubType);
    }
}
我可以这样注册(在应用程序启动中):


我想把我的2美分和其他答案一起放在这里,这有助于在SignalR中找到自己的依赖注入方式,可以使用SimpleInjector,也可以使用其他IoC

使用 如果您决定使用Steven的答案,请确保在开始之前注册您的枢纽路线
var activator = new SimpleInjectorHubActivator(container);
GlobalHost.DependencyResolver.Register(typeof(IHubActivator), () => activator);
RouteTable.Routes.MapHubs();
var lifestyle = Lifestyle.CreateHybrid(
    lifestyleSelector: () => HttpContext.Current != null,
    trueLifestyle: new WebRequestLifestyle(),
    falseLifestyle: Lifestyle.Transient // this is what ninject does
    //falseLifestyle: Lifestyle.Singleton
    //falseLifestyle: new LifetimeScopeLifestyle()
);
using (simpleInjectorContainer.BeginLifetimeScope())
{
    // resolve solve dependencies here
}
public IHub Create(HubDescriptor descriptor)
{
    if (HttpContext.Current == null)
        _container.BeginLifetimeScope();
    return _container.GetInstance(descriptor.HubType) as IHub;
}
public class CommandLifetimeScopeDecorator<TCommand> : ICommandHandler<TCommand>
{
    private readonly Func<ICommandHandler<TCommand>> _handlerFactory;
    private readonly Container _container;

    public CommandLifetimeScopeDecorator(
        Func<ICommandHandler<TCommand>> handlerFactory, Container container)
    {
        _handlerFactory = handlerFactory;
        _container = container;
    }

    [DebuggerStepThrough]
    public void Handle(TCommand command)
    {
        using (_container.BeginLifetimeScope())
        {
            var handler = _handlerFactory(); // resolve scoped dependencies
            handler.Handle(command);
        }
    }
}
container.RegisterManyForOpenGeneric(typeof(ICommandHandler<>), assemblies);

container.RegisterSingleDecorator(
    typeof(ICommandHandler<>),
    typeof(CommandLifetimeScopeDecorator<>)
);
public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var config = new HubConfiguration()
        {
            Resolver = new SignalRSimpleInjectorDependencyResolver(Container)
        };
        app.MapSignalR(config);
    }
}

public class SignalRSimpleInjectorDependencyResolver : DefaultDependencyResolver
{
    private readonly Container _container;
    public SignalRSimpleInjectorDependencyResolver(Container container)
    {
        _container = container;
    }
    public override object GetService(Type serviceType)
    {
        return ((IServiceProvider)_container).GetService(serviceType)
               ?? base.GetService(serviceType);
    }

    public override IEnumerable<object> GetServices(Type serviceType)
    {
        return _container.GetAllInstances(serviceType)
            .Concat(base.GetServices(serviceType));
    }
}
container.Register<MessageHub>(() => new MessageHub(new EFUnitOfWork()));