使用UnityContainer作为SignalR依赖关系解析器

时间:2012-03-15 05:02:50

标签: unity-container signalr

我正在使用Unity作为我的DI容器,在解析我的SignalR集线器时我无法使用它。有人有这个成功吗?我尝试了以下内容:

    public class UnityDependencyResolver : DefaultDependencyResolver
    {
        private readonly IUnityContainer _Container;



     public UnityDependencyResolver (IUnityContainer container)
            {
                _Container = container;
                //edit to add
                container.RegisterInstance<IJavaScriptMinifier>(NullJavaScriptMinifier.Instance);

            }

        public override object GetService(Type serviceType)
        {
            return base.GetService(serviceType) ?? _Container.Resolve(serviceType);
        }

        public override IEnumerable<object> GetServices(Type serviceType)
        {
            return base.GetServices(serviceType) ?? _Container.ResolveAll(serviceType);
        }

    }

但我收到错误消息,表示无法解析SignalR.Infrastructure.IJavaScriptMinifier

3 个答案:

答案 0 :(得分:0)

我有点困惑为什么你先尝试做基本分辨率然后再用单位解析器。通常,如果您要使用自己的实现替换基本实现,则两者都将解析,但您应首先解析,以便返回重写类的实例。例如,假设您要覆盖SignalR中的IConnectionIdFactory。您可以创建自己的类,继承自给定的接口,然后使用Unity注册它。然后你的依赖解析器应该能够解析给定的依赖关系并返回,从不接触SignalR解析器。我把一个小测试应用程序放在一起,我的依赖解析器看起来像这样:

依赖性解析器:

public class UnityResolver : DefaultDependencyResolver
{
    private readonly IUnityContainer _container;
    public UnityResolver(IUnityContainer container)
    {
        _container = container;
    }

    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);
    }
}

测试我们是否具有解析路径是非常重要的,因为如果不存在,Resolve会抛出异常。

为了完整起见,这里是实施:

<强> ConnectionIDFactory:

public class ConnectionIdFactory : IConnectionIdFactory
{                
    public string CreateConnectionId(IRequest request)
    {            
        return Guid.NewGuid().ToString();
    }
}

<强>注册

public class Bootstrapper
{
    public static void Pre_Start()
    {
        Container.DefaultContainer.Instance.RegisterType(
            typeof(IConnectionIdFactory), 
            typeof(Repositories.ConnectionIdFactory), 
            null, 
            new Microsoft.Practices.Unity.ContainerControlledLifetimeManager());

        AspNetHost.SetResolver(new Resolvers.UnityResolver(Container.DefaultContainer.Instance));
    }
}

答案 1 :(得分:0)

昨天我通过以下方式解决了这个问题:

注册容器:

    AspNetHost.SetResolver(dependencyResolver);
    DependencyResolver.SetResolver(dependencyResolver);

<强>解析器:

    public class UnityDependencyResolver : DefaultDependencyResolver, IDependencyResolver
    {
        private readonly IUnityContainer _container;

        public UnityDependencyResolver(IUnityContainer container)
        {
            _container = container;
        }

        #region IDependencyResolver Members

        public override object GetService(Type serviceType)
        {
            try
            {
                return _container.Resolve(serviceType);
            }
            catch
            {
                return base.GetService(serviceType);
            }
        }

        public override IEnumerable<object> GetServices(Type serviceType)
        {
            try
            {
                return _container.ResolveAll(serviceType);
            }
            catch
            {
                return base.GetServices(serviceType);
            }
        }

        #endregion
    }

<强>集线器:

    public class Chat : Hub
    {
        [Dependency]
        public UserService _userService { get; set; }

        public void Send(string message)
        {                
            _userService.SomeMethod();                
        }
    }

完美无缺!

答案 2 :(得分:0)

在Hub中注入Unity容器的另一种方法是创建自己的HubActivator 试试这个。 https://stackoverflow.com/a/30887576/3000736