我想我错过了一些非常简单的事情,也许只需要一副新的眼睛。我有一个ASP.NET MVC应用程序。在那个应用程序中,我使用Unity来处理IoC来处理依赖注入。我的每个存储库都需要注入一个数据库工厂,每个数据库工厂都需要注入一个主体。到目前为止,我一直在使用PerRequestLifetimeManager来注册这些。
//Repositories
container.RegisterType<ChatMessageRepository>(new PerRequestLifetimeManager());
container.RegisterType<SignalRConnectionRepository>(new PerRequestLifetimeManager());
//Context
container.RegisterType<IPrincipal, Principal>(new PerRequestLifetimeManager());
container.RegisterType<IDatabaseFactory, DatabaseFactory>(new PerRequestLifetimeManager());
container.RegisterType<UnitOfWork>(new PerRequestLifetimeManager());
逻辑上,我试图以同样的方式注册我的Hub。
container.RegisterType<ChatHub>(new PerRequestLifetimeManager());
然而,每当我运行我的应用程序并离开我的聊天页面时,我得到“依赖失败的解决方案”异常,而InnerException告诉我“由于对象的当前状态,操作无效”。我也尝试使用默认(Transient),PerResolve和ContainerControlled生命周期Unity管理员注册这些人,似乎无法解决我的问题。
有人可以向我提供一些演示代码,说明如何在ASP.NET MVC应用程序中使用Unity来处理信号中心的依赖注入吗?
Unity将把参数注入我的SignalR Hub
public class ChatHub : Hub
{
private readonly ChatMessageRepository _chatMessageRepository;
private readonly SignalRConnectionRepository _signalRConnectionRepository;
private readonly UnitOfWork _unitOfWork;
public ChatHub(ChatMessageRepository chatMessageRepository,
SignalRConnectionRepository signalRConnectionRepository,
UnitOfWork unitOfWork)
{
_chatMessageRepository = chatMessageRepository;
_signalRConnectionRepository = signalRConnectionRepository;
_unitOfWork = unitOfWork;
} ... }
谢谢!
答案 0 :(得分:16)
分3步完成
首先。创建UnityHubActivator类
public class UnityHubActivator : IHubActivator
{
private readonly IUnityContainer _container;
public UnityHubActivator(IUnityContainer container)
{
_container = container;
}
public IHub Create(HubDescriptor descriptor)
{
return (IHub)_container.Resolve(descriptor.HubType);
}
}
二。在运行Startup class
之前创建Unity容器并注册依赖项解析程序unityContainer = new UnityContainer();
var unityHubActivator = new UnityHubActivator(_unityContainer);
GlobalHost.DependencyResolver.Register(typeof(IHubActivator), () => unityHubActivator);
//register some types in container
WebApp.Start<Startup>(startOptions);
第三。在您的集线器中使用它
public class MyHub : Hub
{
public MyHub(Logger logger)
{
logger.Info("hub constructor");
}
}
请注意。我在Startup类中没有改变任何内容
答案 1 :(得分:1)
有一个技巧可以做到这一点。你需要做这样的事情:
container.RegisterType< ChatHub >(new InjectionFactory(CreateChatHub));
......
然后创建一个私有方法CreateChatHub
private static object CreateChatHub(IUnityContainer container)
{
return new ChatHub();
}
答案 2 :(得分:0)
1创建“ UnitySignalRDependencyResolver.cs”
public class UnitySignalRDependencyResolver : DefaultDependencyResolver
{
protected IUnityContainer Container;
private bool IsDisposed = false;
public UnitySignalRDependencyResolver(IUnityContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
Container = container.CreateChildContainer();
}
/// <summary>
/// Gets the Autofac implementation of the dependency resolver.
/// </summary>
public static UnitySignalRDependencyResolver Current
{
get { return GlobalHost.DependencyResolver as UnitySignalRDependencyResolver; }
}
public override object GetService(Type serviceType)
{
if (Container.IsRegistered(serviceType))
{
return Container.Resolve(serviceType);
}
return base.GetService(serviceType);
}
public override IEnumerable<object> GetServices(Type serviceType)
{
if (Container.IsRegistered(serviceType))
{
return Container.ResolveAll(serviceType);
}
return base.GetServices(serviceType);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (IsDisposed)
{
return;
}
if (disposing)
{
Container.Dispose();
}
IsDisposed = true;
}
}
2。将解析器添加到Owin管道
public class Startup
{
public void Configuration(IAppBuilder app)
{
// Get container
IUnityContainer container = UnityConfig.Container;
// Create resolver
var resolver = new UnitySignalRDependencyResolver(container);
// Create SignalR Configuration
var config = new HubConfiguration
{
Resolver = resolver
};
// Start SignalR
app.Map("/signalr", map =>
{
map.RunSignalR(config);
});
}
}
3。将依赖项注入控制器的构造函数中
public class ValuesController : ApiController
{
private readonly IMyDependency _myDependency;
public ValuesController(IMyDependency myDependency)
{
_myDependency= myDependency;
}
}