首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Autofac和Signalr

Autofac和Signalr
EN

Stack Overflow用户
提问于 2013-02-13 15:47:04
回答 2查看 1.3K关注 0票数 1

我已经在Autofac组上发布了这篇文章,但没有成功。

我使用的是来自Nuget的Autofac3.0.1、SignalR 1.0.0pre2和Autofac.SignalR.3.0.0包。我正在使用Autofac注册类型,但在解析时,我得到了一个

“没有为此对象定义无参数构造函数。”

错误

我的集线器看起来像

代码语言:javascript
复制
public class UserHub : AuthenticatingHub
{
    private readonly IUserService _userService;

    public UserHub(IUserService userService)
    {
        _userService = userService;
    }

我的容器构建器是这样的:

代码语言:javascript
复制
        var builder = new ContainerBuilder();
        builder.RegisterControllers(typeof(MvcApplication).Assembly);

        var serviceAssemblies = Assembly.Load("Services");
        builder.RegisterAssemblyTypes(serviceAssemblies).AsImplementedInterfaces();
        builder.RegisterType<UserHub>();

        var container = builder.Build();

        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
        GlobalHost.DependencyResolver = new Autofac.Integration.SignalR.AutofacDependencyResolver(container);

其中‘服务’引用IUserService

这是与以前版本的SignalR和Autofac一起工作的代码,但使用了不同的Autofac依赖解析器。任何指针都是欢迎的,

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-02-13 17:53:26

确保在对路由集合调用MapHubs()之前设置解析器,此时,对解析器的引用将传递到基础结构中。在调用MapHubs之后设置一个新的解析器将不会做任何事情。

票数 4
EN

Stack Overflow用户

发布于 2014-08-24 13:07:19

互联网上的文档中有很多缺失。我写了一篇关于一起使用Autofac 2.0和SignalR的文章,因为Autofac的文档并不完整:

我写了一篇关于这个的博客文章,但我把这个网站写下来了,这是那篇博客文章的HTML:

在MVC应用程序中通过Autofac大量使用DI,在Signalr 2.0上有问题吗?

您是否遵循Autofacs文档并安装了Autofac.SignalR Nuget包:https://code.google.com/p/autofac/wiki/SignalRIntegration

Autofac的文档存在多个问题,而Autofac.Singalr Nuget包是针对SignalR 1.0的。

因此,首先,让我们使用SignalR 2.0进行修复。您只需向正确的方向推动Autofac.SignalR包,在您的Web.config中添加以下内容:

代码语言:javascript
复制
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

        <dependentAssembly>

            <assemblyIdentity name="Microsoft.AspNet.SignalR.Core" publicKeyToken="31bf3856ad364e35" culture="" />

            <bindingRedirect oldVersion="1.0.0.0" newVersion="2.1.1.0" />

        </dependentAssembly>

    </assemblyBinding>

</runtime>

现在实际运行的代码如下:

代码语言:javascript
复制
public interface IConversationHub

{

    System.Threading.Tasks.Task OnConnected();



    void SendNotifications(long _account_id, int _partition_id, List<long> _userIds,

        DTO.ConversationEventMessage _message);

}



[Authorize]

public class ConversationHub : Hub, IConversationHub

{

    readonly ILifetimeScope _hubLifetimeScope;

    private uTextAPP.AppLayer.IManageUsers _ManageUsers { get; set; }

    private uTextAPP.AppLayer.IManageUserConnections _ManageUserConnections { get; set; }

    private uTextDDD.ServiceLayer.IReportUserConnections _ReportUserConnections { get; set; }



    public ConversationHub(ILifetimeScope lifetimeScope)

    {

        // Create a lifetime scope for the hub.

        _hubLifetimeScope = lifetimeScope.BeginLifetimeScope();



        // Resolve dependencies from the hub lifetime scope.

        _ManageUsers = _hubLifetimeScope.Resolve<uTextAPP.AppLayer.IManageUsers>();

        _ManageUserConnections = _hubLifetimeScope.Resolve<uTextAPP.AppLayer.IManageUserConnections>();

        _ReportUserConnections = _hubLifetimeScope.Resolve<uTextDDD.ServiceLayer.IReportUserConnections>();

    }



    public override System.Threading.Tasks.Task OnConnected()

    {

        //var username = Context.User.Identity.Name; //this is the user_id!! yay!

        var user = _ManageUsers.GetCurrentUser();

        var _issues = new Issues();



        if (user == null || user.account_id == 0)

            return base.OnConnected();



        var conn = new user_connection

               {

                   connection_id = Context.ConnectionId,

                   user_id = user.user_id

               };



        _ManageUserConnections.CreateUserConnection(user.account_id, user.user_id, user.partition_id, conn, _issues);



        return base.OnConnected();

    }





    internal static void SendNotifications(long _account_id, int _partition_id, List<long> _userIds, DTO.ConversationEventMessage _message, IEnumerable<uTextDTO.AppLayer.user_connection> _connections )

    {

        IHubContext context = GlobalHost.ConnectionManager.GetHubContext<ConversationHub>();





        if (_connections == null) return;



        foreach (var c in _connections)

        {

            if (_userIds.Any(_userIds.Contains))

            {

                if (context.Clients.Client(c.connection_id) != null)

                {

                    context.Clients.Client(c.connection_id).receiveNotification(_message);

                }

            }

        }

    }





    public void SendNotifications(long _account_id, int _partition_id, List<long> _userIds, DTO.ConversationEventMessage _message)

    {

          var _issues = new Issues();

        SendMessage(_account_id, _partition_id, _userIds, _message, _ReportUserConnections.GetAllUserConnectionsByDaysBack(_account_id, -1L, _partition_id, 1, _issues))

        ;



    }



    public override Task OnDisconnected(bool stopCalled)

    {

        var user = _ManageUsers.GetCurrentUser();

        var _issues = new Issues();



        if (user == null || user.account_id == 0)

            return base.OnConnected();



        var original = _ManageUserConnections.GetUserConnectionByConnectionId(user.account_id, user.partition_id,

            user.partition_id, Context.ConnectionId, _issues);



        if (original != null && original.user_connection_id != 0L)

        {

            var mod = new user_connection().CopyModelExt(original);

            mod.is_active = false;



            _ManageUserConnections.UpdateUserConnection(user.account_id, user.user_id, user.partition_id, original.user_connection_id,mod, original, _issues);

        }



        return base.OnDisconnected(stopCalled);

    }



    protected override void Dispose(bool disposing)

    {

        // Dipose the hub lifetime scope when the hub is disposed.

        if (disposing && _hubLifetimeScope != null)

            _hubLifetimeScope.Dispose();



        base.Dispose(disposing);

    }

}

首先,请注意上面的代码,公共重写任务OnDisconnected是不可信任的,它不会触发,并且不是管理与SignalR断开连接的可靠方法,这种方法可能会捕获一些断开连接。幸运的是,对于我的需求,我可以忽略超过一天的连接。

下一步注意,使用上面的代码,内部静态空SendNotifications。SendNotifications必须是静态的,这样SignalR上下文才不会在访问时抛出运行时错误。

最后请注意,静态方法是从调用者传递的连接,也就是SendNotifications的公开方法。我需要一个SendNotifications中的IReportUserConnections实例,但IReportUserConnections不是静态的,也不能被Autofac正确注入。所以我不能在静态空SendNotifications中使用IReportsUserConnections,所以我用SendNotifications的公共版本解决了这个问题。

对于Autofac容器:

代码语言:javascript
复制
public static class SimpleInjectorInitializer

{

    public static IContainer Container;



    public static void Initialize()

    {

        var builder = new ContainerBuilder();



                   // Register the SignalR hubs.

                    builder.RegisterHubs(typeof(uTextAPP.SignalR.ConversationHub).Assembly);



        uTextMVC.RegisterMe.Register(builder);



        Container = builder.Build();

        DependencyResolver.SetResolver(new Autofac.Integration.Mvc.AutofacDependencyResolver(Container));



        var signalRDependencyResolver = new Autofac.Integration.SignalR.AutofacDependencyResolver(Container);

        GlobalHost.DependencyResolver = signalRDependencyResolver;

    }

}

互联网上缺少的一个重要部分,就是如何实际使用IoC注入的ConversationHub来发送通知:

代码语言:javascript
复制
public Lazy _ConversationHub { get; set; }
_ConversationHub.Value.SendNotifications(account.account_id, account.partition_id, userIds, convoEv);

您必须确保在Register.me中使用Autofac注册集线器,以便初始化_ConversationHub:

代码语言:javascript
复制
  container.RegisterType<SignalR.ConversationHub>().As<SignalR.IConversationHub>().InstancePerLifetimeScope().PropertiesAutowired();
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14848706

复制
相关文章

相似问题

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