0

IoC 컨테이너 SimpleInjector를 사용하고 있습니다. 싱글 톤은 그 목적이 아니기 때문에 재 작성되어서는 안되지만 문제는 WCF에서 발생하고 에 입력하면 상태입니다. 몇 가지 읽기에 따라 복구 할 수없고 새 인스턴스를 만들어야합니다.SimpleInjector (Tridion 사용)로 Singleton 인스턴스로 WCF 서비스를 다시 만드는 방법

두 개의 WCF 서비스를 사용하는 CoreServiceService 클래스가 있습니다.

  1. CoreService
  2. ECLService

나는 이러한 서비스는 내가 CoreServiceSession에 전화를 많이 만들고 그 WCF 서비스가 너무 비싸고 시간이 많이 걸립니다 생성됩니다 싱글 이후가되고 싶어요, 창작 후 훨씬 더 빠릅니다.

나는이로 등록하고 있습니다 :

container.Register(() => new SessionAwareEclServiceClient(binding, eclServiceRemoteAddress), Lifestyle.Singleton); 

container.Register(() => new SessionAwareCoreServiceClient(binding, coreServiceRemoteAddress), Lifestyle.Singleton); 

container.Register(typeof(ICoreServiceSession), typeof(CoreServiceSession), Lifestyle.Scoped); 

내 문제는 뭔가를 검색 할 수없는 경우 ECLService를 사용하는 동안 그 내가 .Abort을 (전화 케이스)과 가까이에서 오류가 발생한 연결로 진입이다 연결. 하지만 다음 번에 내 서비스를 호출 할 때 ECLService WCF 서비스는 오류 상태 (계속 싱글 톤이므로)로 유지되므로 연결을 다시 만들 수있는 방법이 필요합니다.

나는 물론, 그것은 나에게 같은 인스턴스를 제공

coreServiceSession.EclServiceClient = (SessionAwareEclServiceClient)container.GetInstance(typeof(SessionAwareEclServiceClient)); 

처럼 뭔가를 시도했지만.

coreServiceSession.EclServiceClient = new SessionAwareEclServiceClient(binding, eclServiceRemoteAddress); 

같은 것들 :이

나는이 초기화를

container.RegisterInitializer<ICoreServiceSession>(coreServiceSession => 
{ 
    if (coreServiceSession.EclServiceClient.State == CommunicationState.Faulted) 
    { 
     coreServiceSession.EclServiceClient.Abort(); 
     coreServiceSession.EclServiceClient = null; 
     coreServiceSession.EclServiceClient = (SessionAwareEclServiceClient)container.GetInstance(typeof(SessionAwareEclServiceClient)); 
    } 
} 

같은 일을 사용하여 시도하고 내가 대신 container.GetInstance의 사용하려고했습니다. 어떤 아이디어/옵션?

어쨌든이 경우 새 인스턴스를 가져와야합니까?

UPDATE

이 클래스 CoreServiceSession 사전에

public class CoreServiceSession : ICoreServiceSession 
{ 
     public CoreServiceSession(ISessionAwareCoreService sessionAwareEclServiceClient, SessionAwareCoreServiceClient sessionAwareCoreServiceClient) 
     { 
      EclServiceClient = sessionAwareEclServiceClient; 
      CoreServiceClient = sessionAwareCoreServiceClient; 
     } 

     public ISessionAwareCoreService EclServiceClient { get; set; } 

     public SessionAwareCoreServiceClient CoreServiceClient { get; set; } 

     public string CreateOrGetStubUris(string eclItemUri) 
     { 
      var stubInfo = EclServiceClient.CreateOrGetStubUris(new List<string> { eclItemUri }).FirstOrDefault(); 
     } 
} 

감사의 일부입니다. Guillermo

+0

당신이 어떤 종류의 업데이 트/새로 고침을 강제로 인스턴스에 메서드를 추가 할 수 있습니다

이 당신의 CoreServiceSession 모습 수 어떻게? 고객의 코드를 공유 할 수 있습니까? –

+0

@StinkyTowel 코드의 일부를 추가했습니다. – polonskyg

+0

** ISessionAwareCoreService sessionAwareEclServiceClient **의 구체적인 클라이언트를 생성하는 코드를 추가 할 수 있습니까? –

답변

0

@ScottHannen은 이미 채널을 싱글 톤으로 등록하지 마십시오. 채널을 만드는 데 비용이 많이 들지 않고 채널 공장 만 있습니다.

실제로 WCF 클라이언트 개체를 생성자에 삽입하면 안됩니다. 그것들을 생성자에 주입한다는 것은 이들이 인터셉트, 모의 또는 대체에 사용할 수있는 유용한 추상화이며 그러한 클라이언트를 사용하는 클래스는 일반적으로 WCF에 강하게 결합된다는 것을 의미합니다.

이렇게 생성자에 주입하는 대신 소비자가 ChannelFactory을 사용하여 내부적으로 생성하게하십시오.그러한 ChannelFactory도 일반적으로 삽입 할 필요는 없으며, 개인 정적 필드에 새로 추가 할 수 있습니다.

public class CoreServiceSession : ICoreServiceSession 
{ 
    private static readonly ChannelFactory factory = 
     new ChannelFactory<ISessionAwareCoreService>(myBinding, myEndpoint); 

    public string CreateOrGetStubUris(string eclItemUri) 
    { 
     var client = factory.CreateChannel(); 

     try 
     { 
      return EclServiceClient.CreateOrGetStubUris(
       new List<string> { eclItemUri }).FirstOrDefault(); 
     } 
     finally 
     { 
      try 
      { 
       ((IDisposable)client).Dispose(); 
      } 
      catch 
      { 
       // We need to swallow exceptions thrown by Dispose. 
       // See: https://marcgravell.blogspot.com/2008/11/dontdontuse-using.html 
      } 
     } 
    } 
} 
+1

나는이 접근법을 두 번 성공적으로 여러 번 사용했다. 그러나 IoC의 정신에 입각하여, 일반적으로 IoC에 등록 된 Func ()를 삽입하면 람다가 싱글 톤 ChannelFactory를 사용합니다. 또한 클라이언트의 CleanClose (Try-Finally 블록의 일부)를 수행하도록 확장 메서드를 작성할 수 있습니다 – KRam

관련 문제