C# SimpleInjector.ActivationException,简单喷油器打开信号RR

C# SimpleInjector.ActivationException,简单喷油器打开信号RR,c#,dependency-injection,signalr,signalr-hub,simple-injector,C#,Dependency Injection,Signalr,Signalr Hub,Simple Injector,我在上实现了答案,并且成功地解决了我的服务,直到在Hub类上调用了OnDisconnected。然后,我不得不遵循这个问题作为解决方法,但每当请求hub实例时都会得到一个异常 我得到的例外是: [SimpleInjector.ActivationException]ChatHub类型的注册委托引发了异常。ChatHub注册为“混合Web请求/执行上下文作用域”,但该实例是在混合Web请求/执行上下文作用域的上下文之外请求的 堆栈跟踪: at SimpleInjector.InstanceProd

我在上实现了答案,并且成功地解决了我的服务,直到在Hub类上调用了
OnDisconnected
。然后,我不得不遵循这个问题作为解决方法,但每当请求hub实例时都会得到一个异常

我得到的例外是:

[SimpleInjector.ActivationException]ChatHub类型的注册委托引发了异常。ChatHub注册为“混合Web请求/执行上下文作用域”,但该实例是在混合Web请求/执行上下文作用域的上下文之外请求的

堆栈跟踪:

at SimpleInjector.InstanceProducer.GetInstance()
at SimpleInjector.Container.GetInstance(Type serviceType)
at QuickChat.Hubs.SimpleInjectorHubActivator.Create(HubDescriptor descriptor) in c:\Users\Peter\Documents\Visual Studio 2013\Projects\QuickChat\QuickChat\Hubs\SimpleInjectorHubActivator.cs:line 21
at Microsoft.AspNet.SignalR.Hubs.DefaultHubManager.ResolveHub(String hubName)
at Microsoft.AspNet.SignalR.Hubs.HubDispatcher.CreateHub(IRequest request, HubDescriptor descriptor, String connectionId, StateChangeTracker tracker, Boolean throwIfFailedToCreate)

InnerException: 

at SimpleInjector.Scope.GetScopelessInstance[TService,TImplementation](ScopedRegistration`2 registration)
at SimpleInjector.Scope.GetInstance[TService,TImplementation](ScopedRegistration`2 registration, Scope scope)
at SimpleInjector.Advanced.Internal.LazyScopedRegistration`2.GetInstance(Scope scope)
at lambda_method(Closure )
at SimpleInjector.InstanceProducer.GetInstance()
请参阅下面我的当前代码配置。 轮毂激活器:

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);
    }
}
SimpleInjector服务注册:

public class SimpleInjectorConfig
{
    public static void Register()
    {
        // Create the container as usual.
        var container = new Container();

        var hybrid = Lifestyle.CreateHybrid(
            () => container.GetCurrentExecutionContextScope() != null,
            new SimpleInjector.Integration.Web.WebRequestLifestyle(),
            new ExecutionContextScopeLifestyle());

        // Register types:
        container.RegisterSingle<MembershipRebootConfiguration>(MembershipRebootConfig.Create);
        container.Register<DefaultMembershipRebootDatabase>(() => new CustomMembershipRebootDatabase());
        container.Register<UserAccountService>(() => new UserAccountService(container.GetInstance<MembershipRebootConfiguration>(), container.GetInstance<IUserAccountRepository>()));
        container.Register<AuthenticationService, SamAuthenticationService>();
        container.RegisterPerWebRequest<IUserAccountQuery, DefaultUserAccountRepository>();
        container.RegisterPerWebRequest<IUserAccountRepository, DefaultUserAccountRepository>();

        container.Register(() => new DataAccess.EF.DataContext(), hybrid);
        container.Register<IUnitOfWork, UnitOfWork>(hybrid);
        container.Register<IUserService, UserService>(hybrid);

        //Register SimpleAuthentication callback provider class
        container.RegisterPerWebRequest<IAuthenticationCallbackProvider, SimpleAuthenticationProviderController>();
        //Register SimpleAuthentication MVC controller.
        container.RegisterPerWebRequest<SimpleAuthenticationController>(
            () => new SimpleAuthenticationController(container.GetInstance<IAuthenticationCallbackProvider>(), null));

        // This is an extension method from the integration package.
        container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
        // This is an extension method from the integration package as well.
        container.RegisterMvcIntegratedFilterProvider();
        //Enable injections to SignalR Hubs
        var activator = new SimpleInjectorHubActivator(container);
        container.Register<ChatHub, ChatHub>(hybrid);
        GlobalHost.DependencyResolver.Register(typeof(IHubActivator), () => activator);

        container.Verify();
        //Set dependency resolver for MVC
        DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
    }
}

你的混合生活方式是错误的。您应该将谓词转过来:

var hybrid = Lifestyle.CreateHybrid(
    () => container.GetCurrentExecutionContextScope() != null,
    new ExecutionContextScopeLifestyle(),
    new SimpleInjector.Integration.Web.WebRequestLifestyle());
var hybrid = Lifestyle.CreateHybrid(
() => container.GetCurrentExecutionContextScope() != null,
new ExecutionContextScopeLifestyle(),
new SimpleInjector.Integration.Web.WebRequestLifestyle());
提示:除了在整个合成根目录中重用该
混合
变量外,还可以将其设置为默认范围的生活方式,如下所示:

container.Options.DefaultScopedLifestyle = hybrid;
通过这种方式,您可以将注册更改为以下内容:

container.Register<ChatHub, ChatHub>(Lifestyle.Scoped);
container.Register(lifesture.Scoped);

这使您的注册更容易、更干净。

您的混合生活方式是错误的。您应该将谓词转过来:

var hybrid = Lifestyle.CreateHybrid(
    () => container.GetCurrentExecutionContextScope() != null,
    new ExecutionContextScopeLifestyle(),
    new SimpleInjector.Integration.Web.WebRequestLifestyle());
var hybrid = Lifestyle.CreateHybrid(
() => container.GetCurrentExecutionContextScope() != null,
new ExecutionContextScopeLifestyle(),
new SimpleInjector.Integration.Web.WebRequestLifestyle());
提示:除了在整个合成根目录中重用该
混合
变量外,还可以将其设置为默认范围的生活方式,如下所示:

container.Options.DefaultScopedLifestyle = hybrid;
通过这种方式,您可以将注册更改为以下内容:

container.Register<ChatHub, ChatHub>(Lifestyle.Scoped);
container.Register(lifesture.Scoped);

这使您的注册更容易、更干净。

您的混合生活方式是错误的。您应该将谓词转过来:

var hybrid = Lifestyle.CreateHybrid(
    () => container.GetCurrentExecutionContextScope() != null,
    new ExecutionContextScopeLifestyle(),
    new SimpleInjector.Integration.Web.WebRequestLifestyle());
var hybrid = Lifestyle.CreateHybrid(
() => container.GetCurrentExecutionContextScope() != null,
new ExecutionContextScopeLifestyle(),
new SimpleInjector.Integration.Web.WebRequestLifestyle());
提示:除了在整个合成根目录中重用该
混合
变量外,还可以将其设置为默认范围的生活方式,如下所示:

container.Options.DefaultScopedLifestyle = hybrid;
通过这种方式,您可以将注册更改为以下内容:

container.Register<ChatHub, ChatHub>(Lifestyle.Scoped);
container.Register(lifesture.Scoped);

这使您的注册更容易、更干净。

您的混合生活方式是错误的。您应该将谓词转过来:

var hybrid = Lifestyle.CreateHybrid(
    () => container.GetCurrentExecutionContextScope() != null,
    new ExecutionContextScopeLifestyle(),
    new SimpleInjector.Integration.Web.WebRequestLifestyle());
var hybrid = Lifestyle.CreateHybrid(
() => container.GetCurrentExecutionContextScope() != null,
new ExecutionContextScopeLifestyle(),
new SimpleInjector.Integration.Web.WebRequestLifestyle());
提示:除了在整个合成根目录中重用该
混合
变量外,还可以将其设置为默认范围的生活方式,如下所示:

container.Options.DefaultScopedLifestyle = hybrid;
通过这种方式,您可以将注册更改为以下内容:

container.Register<ChatHub, ChatHub>(Lifestyle.Scoped);
container.Register(lifesture.Scoped);

这使您的注册更容易、更干净。

正如史蒂文在回答中所说,我的混合生活方式是错误的。我必须把谓词转过来:

var hybrid = Lifestyle.CreateHybrid(
    () => container.GetCurrentExecutionContextScope() != null,
    new ExecutionContextScopeLifestyle(),
    new SimpleInjector.Integration.Web.WebRequestLifestyle());
var hybrid = Lifestyle.CreateHybrid(
() => container.GetCurrentExecutionContextScope() != null,
new ExecutionContextScopeLifestyle(),
new SimpleInjector.Integration.Web.WebRequestLifestyle());
与史蒂文讨论了几次之后,我得出了一个结论

我必须使我的
ChatHub
a并从中提取所有逻辑,然后将其放入一个单独的类中,该类实现了一个服务接口,该接口由公开最初包含在
ChatHub
中的所有逻辑的方法组成

public interface IChatService
{
    void OnConnected(Guid userId, string connectionId, HubConnectionContext clients);
    void OnDisconnected(Guid userId, string connectionId);
    void Broadcast(string message, string username, HubConnectionContext clients);
}

public class ChatService : IChatService
{
    private readonly IUnitOfWork _unitOfWork;
    public UserChatService(IUnitOfWork unitOfWork) {
        _unitOfWork = unitOfWork;
    }

    public void OnConnected(Guid userId, string connectionId, HubConnectionContext clients) { 
        //Perform other operation using _unitOfWork
    }
    public void OnDisconnected(Guid userId, string connectionId) {
        //Perform other operation using _unitOfWork
    }
    public void Broadcast(string message, string username, HubConnectionContext clients) { 
        //Perform other operation using _unitOfWork and HubConnectionContext
        //broadcast message to other connected clients
        clients.others.broadcast(message);
    }
}
HubConnectionContext
在我看来确实像是运行时数据,所以我决定将其作为参数传递给这些方法

这样,我的hub
ChatHub
看起来很轻量级,将调用委托给
ChatService
对象,当调用hub的
OnDisconnected()
时,我不再遇到错误

不要忘记在容器中注册您的服务:

container.Register<IChatService, ChatService>(hybrid);
容器寄存器(混合);

正如史蒂文在回答中所说,我的混合生活方式是错误的。我必须把谓词转过来:

var hybrid = Lifestyle.CreateHybrid(
    () => container.GetCurrentExecutionContextScope() != null,
    new ExecutionContextScopeLifestyle(),
    new SimpleInjector.Integration.Web.WebRequestLifestyle());
var hybrid = Lifestyle.CreateHybrid(
() => container.GetCurrentExecutionContextScope() != null,
new ExecutionContextScopeLifestyle(),
new SimpleInjector.Integration.Web.WebRequestLifestyle());
与史蒂文讨论了几次之后,我得出了一个结论

我必须使我的
ChatHub
a并从中提取所有逻辑,然后将其放入一个单独的类中,该类实现了一个服务接口,该接口由公开最初包含在
ChatHub
中的所有逻辑的方法组成

public interface IChatService
{
    void OnConnected(Guid userId, string connectionId, HubConnectionContext clients);
    void OnDisconnected(Guid userId, string connectionId);
    void Broadcast(string message, string username, HubConnectionContext clients);
}

public class ChatService : IChatService
{
    private readonly IUnitOfWork _unitOfWork;
    public UserChatService(IUnitOfWork unitOfWork) {
        _unitOfWork = unitOfWork;
    }

    public void OnConnected(Guid userId, string connectionId, HubConnectionContext clients) { 
        //Perform other operation using _unitOfWork
    }
    public void OnDisconnected(Guid userId, string connectionId) {
        //Perform other operation using _unitOfWork
    }
    public void Broadcast(string message, string username, HubConnectionContext clients) { 
        //Perform other operation using _unitOfWork and HubConnectionContext
        //broadcast message to other connected clients
        clients.others.broadcast(message);
    }
}
HubConnectionContext
在我看来确实像是运行时数据,所以我决定将其作为参数传递给这些方法

这样,我的hub
ChatHub
看起来很轻量级,将调用委托给
ChatService
对象,当调用hub的
OnDisconnected()
时,我不再遇到错误

不要忘记在容器中注册您的服务:

container.Register<IChatService, ChatService>(hybrid);
容器寄存器(混合);

正如史蒂文在回答中所说,我的混合生活方式是错误的。我必须把谓词转过来:

var hybrid = Lifestyle.CreateHybrid(
    () => container.GetCurrentExecutionContextScope() != null,
    new ExecutionContextScopeLifestyle(),
    new SimpleInjector.Integration.Web.WebRequestLifestyle());
var hybrid = Lifestyle.CreateHybrid(
() => container.GetCurrentExecutionContextScope() != null,
new ExecutionContextScopeLifestyle(),
new SimpleInjector.Integration.Web.WebRequestLifestyle());
与史蒂文讨论了几次之后,我得出了一个结论

我必须使我的
ChatHub
a并从中提取所有逻辑,然后将其放入一个单独的类中,该类实现了一个服务接口,该接口由公开最初包含在
ChatHub
中的所有逻辑的方法组成

public interface IChatService
{
    void OnConnected(Guid userId, string connectionId, HubConnectionContext clients);
    void OnDisconnected(Guid userId, string connectionId);
    void Broadcast(string message, string username, HubConnectionContext clients);
}

public class ChatService : IChatService
{
    private readonly IUnitOfWork _unitOfWork;
    public UserChatService(IUnitOfWork unitOfWork) {
        _unitOfWork = unitOfWork;
    }

    public void OnConnected(Guid userId, string connectionId, HubConnectionContext clients) { 
        //Perform other operation using _unitOfWork
    }
    public void OnDisconnected(Guid userId, string connectionId) {
        //Perform other operation using _unitOfWork
    }
    public void Broadcast(string message, string username, HubConnectionContext clients) { 
        //Perform other operation using _unitOfWork and HubConnectionContext
        //broadcast message to other connected clients
        clients.others.broadcast(message);
    }
}
HubConnectionContext
在我看来确实像是运行时数据,所以我决定将其作为参数传递给这些方法

这样,我的hub
ChatHub
看起来很轻量级,将调用委托给
ChatService
对象,当调用hub的
OnDisconnected()
时,我不再遇到错误

不要忘记在容器中注册您的服务:

container.Register<IChatService, ChatService>(hybrid);
容器寄存器(混合);

正如史蒂文在回答中所说,我的混合生活方式是错误的。我必须把谓词转过来:

var hybrid = Lifestyle.CreateHybrid(
    () => container.GetCurrentExecutionContextScope() != null,
    new ExecutionContextScopeLifestyle(),
    new SimpleInjector.Integration.Web.WebRequestLifestyle());
var hybrid = Lifestyle.CreateHybrid(
() => container.GetCurrentExecutionContextScope() != null,
new ExecutionContextScopeLifestyle(),
new SimpleInjector.Integration.Web.WebRequestLifestyle());
与史蒂文讨论了几次之后,我得出了一个结论

我必须使我的
ChatHub
a并从中提取所有逻辑,然后将其放入一个单独的类中,该类实现了一个服务接口,该接口由公开最初包含在
ChatHub
中的所有逻辑的方法组成

public interface IChatService
{
    void OnConnected(Guid userId, string connectionId, HubConnectionContext clients);
    void OnDisconnected(Guid userId, string connectionId);
    void Broadcast(string message, string username, HubConnectionContext clients);
}

public class ChatService : IChatService
{
    private readonly IUnitOfWork _unitOfWork;
    public UserChatService(IUnitOfWork unitOfWork) {
        _unitOfWork = unitOfWork;
    }

    public void OnConnected(Guid userId, string connectionId, HubConnectionContext clients) { 
        //Perform other operation using _unitOfWork
    }
    public void OnDisconnected(Guid userId, string connectionId) {
        //Perform other operation using _unitOfWork
    }
    public void Broadcast(string message, string username, HubConnectionContext clients) { 
        //Perform other operation using _unitOfWork and HubConnectionContext
        //broadcast message to other connected clients
        clients.others.broadcast(message);
    }
}
HubConnectionContext
在我看来确实像是运行时数据,所以我决定将其作为参数传递给这些方法

这样,我的hub
ChatHub
看起来很轻量级,将调用委托给
ChatService
对象,当调用hub的
OnDisconnected()
时,我不再遇到错误

不要忘记在容器中注册您的服务:

container.Register<IChatService, ChatService>(hybrid);
容器寄存器(混合);

我仍然有一个错误,但那只是