2014-02-13 4 views
2

내 응용 프로그램은 "SignalR"클라이언트/서버 통신 프레임 워크를 사용합니다. 익숙하지 않은 경우 일반적으로 서버 측 응용 프로그램에는 클라이언트가 호출 할 수있는 메서드를 제공하는 하나 이상의 "허브"클래스 (asmx 웹 서비스와 유사)가 포함되어 있습니다.성 윈저 - 이름으로 해결하는 방법?

var hubConnection = new HubConnection("http://..."); 
var fooHubProxy = hubConnection.CreateHubProxy("FooHub"); 
var barHubProxy = hubConnection.CreateHubProxy("BarHub"); 
...etc... 

CreateHubProxy()에 전달 된 문자열 매개 변수의 이름입니다 -이 : 시작하는 동안, 클라이언트는 먼저는, 예를 들어 얘기해야 각 허브에 대해 "프록시"를 생성, 연결을 만들어야합니다 서버 측 허브 클래스. 메서드 반환 유형은 IHubProxy입니다.

내가 여기 윈저를 이용할 수 있어야한다고 느낀다. 그러나 나는 해결책을 찾기 위해 고심하고있다. 내 첫 번째 생각은 허브 프록시를 인스턴스화하고 이러한 인스턴스를 Windsor (이름으로)에 등록하는 것이 었습니다.

var fooHubProxy = hubConnection.CreateHubProxy("FooHub"); 
container.Register(Component.For<IHubProxy>().Instance(fooHubProxy).LifestyleSingleton().Named("FooHub")); 
...etc... 

문제는 클래스가 허브 프록시를 필요로 할 때 이름은 사용하지 않는 것이 좋습니다 서비스 로케이터 패턴을 사용하는 것입니다으로, 유일한 방법은 그것을 해결하는 것입니다. 다른 Windsor 기능 (예 : 입력 된 공장 등)이 여기에서 유용 할 수 있습니까?

편집

난 그냥 윈저의 .UsingFactoryMethod 발견했습니다, 이것은 작동 할 허브 등록 단순화하는 경우 궁금 :

container.Register(Component.For<IHubProxy>() 
        .UsingFactoryMethod((kernel, context) => hubConnection.CreateHubProxy("FooHub")) 
        .LifestyleSingleton() 
        .Named("FooHub")); 

나는 아직도 해결하는 방법의 문제가 생각을 그래도 이름으로.

답변

2

좋아요, 가능한 해결책을 찾았습니다. 부분적으로는 here 접근 방식을 사용하여 Func<>을 Windsor에 등록하는 방법을 보여줍니다. IHubProxy "공장"으로 이것의

Container.Register(Component.For<Func<string, IHubProxy>>() 
        .Instance(name => Container.Resolve<IHubProxy>(name)) 
        .LifestyleSingleton()); 

생각해 - :

첫째, 나는 이름으로 해결하기 위해 컨테이너를 사용하는 대리인 (Func을 <를>) 등록합니다.

public class SomeClass 
{ 
    private IHubProxy _fooHub; 
    private IHubProxy _barHub; 

    public SomeClass(Func<string, IHubProxy> hubProxyFactory) 
    { 
     _fooHub = hubProxyFactory("FooHub"); 
     _barHub = hubProxyFactory("BarHub"); 
    } 
} 

미결 - :

여기
container.Register(Component.For<IHubProxy>() 
       .UsingFactoryMethod((kernel, context) => hubConnection.CreateHubProxy("FooHub")) 
       .LifestyleSingleton() 
       .Named("FooHub")); 
container.Register(Component.For<IHubProxy>() 
       .UsingFactoryMethod((kernel, context) => hubConnection.CreateHubProxy("BarHub")) 
       .LifestyleSingleton() 
       .Named("BarHub")); 

허브 프록시의 인스턴스를 필요로하는 클래스의 예입니다 -이 : 내 원래의 질문에 설명 된대로

다음, 내 허브 프록시를 등록 지금까지는 유망 해 보입니다. 영리한 솔루션이지만 Func <을 주입하면 약간의 해킹이 느껴 지므로 제 문제에 대한 다른 가능한 해결책을 듣고 싶습니다.

1

방금 ​​당신과 비슷한 방법을 사용했습니다. 나는 형식화 된 공장을 사용합니다. 이점은 허브에 대한 유형 안전성입니다. 허브 등록은 동일합니다. 나머지는 조금 다르지만 기술은 동일합니다.

IServiceFactory { 
    IHubProxy GetFooHub(); 
    IHubProxy GetBarHub(); 
} 

및 등록 :

Container.AddFacility<TypedFactoryFacility>(); 
Container.Register(Component.For<IServiceFactory>().AsFactory()); 

사용법 : Btw는

public class SomeClass 
{ 
    private IHubProxy _fooHub; 
    private IHubProxy _barHub; 

    public SomeClass(IServiceFactry hubProxyFactory) 
    { 
     _fooHub = hubProxyFactory.GetFooHub(); 
     _barHub = hubProxyFactory.GetBarHub(); 
    } 
} 

. Factory.Get"Name"()은 이름으로 결정됩니다.

4

2 년 후,하지만이 문제에 대해서도 너무 많은 다른 사람들을위한 더 우아한 솔루션이 있습니다. TypedFactory 기능을 사용하고 here과 같이 필요에 맞게 조정할 수 있습니다. 먼저 팩토리 인터페이스 생성 (! 실제 구현 만 필요 없음, 성 그 처리됩니다) :

public interface IHubProxyFactory 
{ 
    IHubProxy GetProxy(string proxyName); 
} 

이제 우리는 기본이 facotory 입력 확장하고 입력에서 구성 요소의 이름을 꺼냅니다 클래스를 필요 (proxyName) :

class NamedTypeFactory : DefaultTypedFactoryComponentSelector 
{ 
    protected override string GetComponentName(MethodInfo method, object[] arguments) 
    { 
     string componentName = null; 
     if (arguments!= null && arguments.Length > 0) 
     { 
      componentName = arguments[0] as string; 
     } 

     if (string.IsNullOrEmpty(componentName)) 
      componentName = base.GetComponentName(method, arguments); 

     return componentName; 
    } 
} 

그리고 성 공장을 등록하고 NamedTypeFactory이 사용됨을 지정

Component.For<IHubProxyFactory>().AsFactory(new NamedTypeFactory()) 

이제 모든 클래스는 생성자에서 팩토리 인터페이스를 가져올 수 있습니다.

public class SomeClass 
{ 
    private IHubProxy _fooHub; 
    private IHubProxy _barHub; 

    public SomeClass(IHubProxyFactory hubProxyFactory) 
    { 
     _fooHub = hubProxyFactory.GetProxy("FooHub"); 
     _barHub = hubProxyFactory.GetProxy("BarHub"); 
    } 
}