2013-08-02 3 views
2

이 방법이 가능한지 확인하려고합니다. 성 클래스 윈저에서 WCF 서비스 클래스를 팩토리 클래스를 통해 해결하려고합니다. WCF 서비스는 IIS에서 호스팅되며 지금까지 팩토리를 사용할 때 서비스를 호출하려고했을 때만 404가 표시되었습니다.WCF 서비스를 사용하여 Castle Windsor를 사용하여 메서드를 사용하여

container.AddFacility<WcfFacility>(); 

container.Register(Component.For<IServiceFactory>() 
          .ImplementedBy<ServiceFactory>() 
          .LifestyleSingleton()); 

container.Register(Component.For<IFooService>() 
          .UsingFactoryMethod((kernel, context) 
            => kernel.Resolve<IServiceFactory>() 
                .CreateService(context.RequestedType))          
          .Named("FooService") 
          .LifestylePerWcfOperation()); 

여기 내 공장 클래스입니다 : 여기 내 등록 코드

public class ServiceFactory : IServiceFactory 
{ 
    public IFooService CreateService(Type forType) 
    { 
     IFooService createdType = null; 

     if (forType == typeof(IFooService)) 
      createdType = new FooService(); 

     return createdType; 
    } 
} 

내가 시도 해협 .ImplementedBy <FooService>()을 수행하고 잘 작동합니다. 제가 문제가있는 공장을 통해서만 그것을하고 싶을 때입니다. 이것이 가능합니까, 내가 뭔가를 놓치고 있다는 것을 의미합니까, 아니면 불가능합니까?

(I가 표시된 코드는 아주 간단합니다 알고, 난 단지 테스트입니다 경우의 수 완전히 내 공장 코드를 구현하기 전에)

+0

구현했을 때, 내가 생각했던 것보다 * 많이 * 간단하지 않았습니다. 대략 3 개 또는 4 개의 클래스를 만들어야한다고 생각합니다. 여기에 설명 된대로 (그냥 윈저로 단일체 규칙을 대체하십시오) : http://www.i-avington.com/Posts/Post/usng-unity-with-a-wcf- service – eouw0o83hf

+0

나는 내 자신의 ServiceHostFactory를 작성해야 할 것 같았습니다. 나는이 질문을 먼저하기로 결정했다. – Chris

+0

그래, 나는 그 일을 할 필요가 없도록 열심히 노력했지만, 뭔가 바뀌지 않는 한 그 주위에는 어떤 방법도 보이지 않는다. 죄송합니다 : -/ – eouw0o83hf

답변

0

을 당신이하지 이 할 수있는 사용자 정의하여 ServiceHost를 생성해야하지만 할 네가 맞아, 이것이해야 할 것보다 더 힘들다. eww0o83hf가 처음 참조하는 기사는 IInstanceProvider에 대해 이야기합니다. 이것이 핵심이지만 ServiceHost 고객 대신 WCF ServiceBehavior를 사용하여 연결할 수 있습니다. FactoryMethod가이 작업과 관련이 있는지 확신 할 수 없습니다. 일반적인 와이어 문제처럼 들리거나 문제를 이해하지 못하는 것 같습니다. 아래에 ServiceHost없이 와이어를 어떻게 처리하는지 보여주고 잘하면이 문제를 해결합니다.

우선 IInstanceProvider를 구현하는 클래스를 만듭니다. Winner가 랩핑 된 ObjectResolver 클래스를 호출하는 것보다 아래에 있습니다. 나는 간결함을 위해 그 것을 버릴 것이다. ...

using System; 
using System.Collections.ObjectModel; 
using System.ServiceModel; 
using System.ServiceModel.Channels; 
using System.ServiceModel.Description; 
using System.ServiceModel.Dispatcher; 

public class ConstructWithObjectResolverAttribute : Attribute, IServiceBehavior 
{ 
    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
    { 
     foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers) 
     { 
      ChannelDispatcher cd = cdb as ChannelDispatcher; 

      if (cd != null) 
      { 
       foreach (EndpointDispatcher ed in cd.Endpoints) 
       { 
        ed.DispatchRuntime.InstanceProvider = new ObjectResolverInstanceProvider(serviceDescription.ServiceType); 
       } 
      } 
     } 
    } 

    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) 
    { 
    } 

    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
    { 
    } 
} 

다음 서비스 구현에 서비스 특성을 적용하면 설정하는 경우에이 작업을 수행 할 수 있습니다 :

using System; 
using System.ServiceModel; 
using System.ServiceModel.Channels; 
using System.ServiceModel.Dispatcher; 

public class ObjectResolverInstanceProvider : IInstanceProvider 
{ 
    private readonly Type _serviceType; 

    public ObjectResolverInstanceProvider(Type serviceType) 
    { 
     _serviceType = serviceType; 
    } 

    public object GetInstance(InstanceContext instanceContext) 
    { 
     return ObjectResolver.Resolve(_serviceType); 
    } 

    public object GetInstance(InstanceContext instanceContext, Message message) 
    { 
     return ObjectResolver.Resolve(_serviceType); 
    } 

    public void ReleaseInstance(InstanceContext instanceContext, object instance) 
    { 
     ObjectResolver.Release(instance); 
    } 
} 

그런 다음 각 엔드 포인트의 DispatchRuntime의 InstanceProvider에 인스턴스 제공자를 할당하는 서비스 동작을 만들 당신도 원했지 만 다음과 같은 속성을 통해 적용하는 것이 더 좋습니다.

[ConstructWithObjectResolver] 
    [ServiceBehavior(Namespace="YourNamespace")] 
    public class FooService : IFooService {} 
+0

자세한 답변을 보내 주셔서 감사합니다! 일반적으로 Castle Windsor의 WCF 시설은 이미 수행 한 작업입니다. 나는 런타임에 팩토리 클래스를 통해 동적으로 서비스 클래스를 변경할 수 있기를 원했다. Castle 윈저는 서비스 호스트 팩토리의 CreateServiceHost 메소드를 오버라이드 (override) 한 방식 때문에 성 윈서에서는 불가능한 것으로 보입니다. – Chris

+0

OK - WcfFacility를 사용하고 있습니다. 나는 아직도 당신이 성취하려는 것을 혼란스러워합니다. 나는 당신의 질문을 몇 번 읽었고 윈저가 실제로 인스턴스화를시키지 않으려 고 노력하고 있지만, 당신 자신의 창조물에 대한 팩토리 클래스를 가지고 있다고 생각하십니까? 나는 당신이 그것에 대한 좋은 이유가 있다고 가정 할 것입니다 ... 왜 당신은 위의 IInstanceProvider 기술을 할 수 없으며 당신의 타입 스위치를 넣을 수 있습니까?윈저가 서비스 인스턴스화를시키지 않는다면 어쨌든 그 시설이 당신을 위해 무엇을하고 있는지를 회피하지 않는 것입니까? – kellyb

+0

"어쨌든 시설이 당신을 위해하는 일을 많이 회피하지 않습니까?"예, 아니오. 의사 결정과 등록을 분리하려고합니다. 그러나 윈저가 그런 것을 좋아하지 않는다고 생각하면, 당신이 개설 한 것을 사용해야 할 것입니다. – Chris