Использование UnityContainer в качестве средства разрешения зависимостей SignalR - PullRequest
0 голосов
/ 15 марта 2012

Я использую 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 голосов
/ 26 марта 2012

Вчера я решил эту проблему следующим образом:

Регистрация контейнера:

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

Resolver:

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

Отлично работает!

0 голосов
/ 17 июня 2015

Еще один способ добавить контейнер Unity в ваш Hub - создать свой собственный HubActivator. Попробуй это. https://stackoverflow.com/a/30887576/3000736

0 голосов
/ 18 марта 2012

Я немного сбит с толку относительно того, почему вы сначала пытаетесь выполнить базовое разрешение, а затем - средство разрешения единства. Как правило, если вы собираетесь заменить базовые реализации своими собственными, обе решат, но ваша должна быть первой, чтобы был возвращен экземпляр вашего переопределяющего класса. Например, скажем, вы хотите переопределить IConnectionIdFactory в SignalR. Вы можете создать свой собственный класс, который наследуется от данного интерфейса, а затем зарегистрировать его в Unity. Тогда ваш распознаватель зависимостей должен иметь возможность разрешать данную зависимость и возвращать ее, никогда не касаясь распознавателя SignalR. Я собрал небольшое тестовое приложение, и мой распознаватель зависимостей выглядит так:

Respendancy Resolver:

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