我在Autofac小组上发布了这个没有运气。
我正在使用Nuget的Autofac3,0.1,SignalR 1.0.0pre2和Autofac.SignalR.3.0.0软件包。我正在使用Autofac注册类型但是 在解决方案我得到了
“没有为此对象定义无参数构造函数。”
错误
我的中心看起来像
public class UserHub : AuthenticatingHub
{
private readonly IUserService _userService;
public UserHub(IUserService userService)
{
_userService = userService;
}
和我的容器构建器一样:
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依赖性解析器。任何指针都欢迎,
由于
答案 0 :(得分:4)
确保在路由集合上调用MapHubs()之前设置解析器,此时对解析器的引用将被传递到基础结构中。在调用MapHubs之后设置一个新的解析器将不会做任何事情。
答案 1 :(得分:1)
互联网上的文档中有很多内容。我写了一起使用SignalR 2.0和Autofac,因为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中:
<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>
现在实际工作的实际代码:
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断开连接的可靠方法,这种方法可能会捕获一些断开连接。幸运的是,根据我的要求,我可以忽略超过一天的连接。
接下来请注意,使用上面的代码,内部静态void SendNotifications。 SendNotifications必须是静态的,以便SignalR Context在访问时不会抛出运行时错误。
最后请注意静态方法是从调用者传递的连接,SendNotifications的公开方法。我在SendNotifications中需要一个IReportUserConnections实例,但IReportUserConnections不是静态的,并且不能是静态的,无法正确地注入Autofac。所以我不能在静态void SendNotifications中使用IReportsUserConnections,所以我用SendNotifications的公共版本解决了这个问题。
对于Autofac容器:
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发送通知:
public Lazy _ConversationHub { get; set; }
_ConversationHub.Value.SendNotifications(account.account_id, account.partition_id, userIds, convoEv);
您必须确保在Register.me中使用Autofac注册Hub,以便初始化_ConversationHub:
container.RegisterType<SignalR.ConversationHub>().As<SignalR.IConversationHub>().InstancePerLifetimeScope().PropertiesAutowired();