2012-03-15 2 views
0

Я использую Unity в качестве контейнера DI, и я не смог заставить его работать при разрешении концентраторов SignalR. Кто-нибудь имел успех в этом? Я попытался следующим:Использование UnityContainer в качестве Resalver Dependency 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

+0

Вы зарегистрировались в реализации 'IJavaScriptMinifier' с Unity? –

+0

Я пробовал это после того, как я разместил это, но это было похоже на хак. (Я отредактирую сообщение, чтобы показать, как). Я не использую явно его использование, и это интерфейс SignalR. – timDunham

+0

Возможно, вы явно не используете его в своем приложении. Но если ваша инфраструктура зависит от нее, а SignalR использует «DependencyResolver» для реализации «IJavaScriptMinifier», вам необходимо зарегистрировать его в своем контейнере. Я бы не зарегистрировал его внутри конструктора распознавателя, но вместе со всеми вашими зависимостями в корне приложения вашего приложения. –

ответ

0

Я немного запутался, почему вы пытаетесь сделать базовое разрешение первым, а затем второй резольвер единства. Как правило, если вы собираетесь заменить базовые реализации своей собственной, обе будут разрешаться, но ваш должен быть первым, чтобы возвращался экземпляр вашего переопределяющего класса. Например, скажем, вы хотите переопределить IConnectionIdFactory в SignalR. Вы можете создать свой собственный класс, который наследуется от данного интерфейса, а затем зарегистрировать его с помощью 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)); 
    } 
} 
+0

Спасибо за ответ. Сначала я сначала проверял свой контейнер, а затем базовый класс, но продолжал работать в ошибке «IJavaScriptMinifier», о которой я упоминал. Я думал, что это может иметь какое-то отношение к Unity, поскольку образец (используя Ninject), похоже, работает. В конце концов, я думаю, что это может быть ошибка в SignalR. – timDunham

+0

@timDunham нет, это не ошибка в signalR, если он не может быть разрешен, просто верните нуль, а SignalR поступит правильно. Ошибка, которую вы видите, - от Unity, а не от SignalR. Как уже упоминалось, Unity генерирует исключение при вызове для решения для незарегистрированной службы. –

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 
    } 

Hub:

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

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

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

+1

Использование catch, чтобы поймать исключения исключений, является плохим и замедляет производительность, гораздо лучше определить, возможно ли разрешение с помощью if. –

+0

Спасибо за предложение Jan. Я попробую это сегодня вечером и дам вам отзывы. – timDunham

+0

Gary.S -> Правильно. Thanx для заметки. –

Смежные вопросы