0

하나의 인스턴스가있는 상태 비 저장 서비스 내에 WebApi 컨트롤러를 호스팅하고 있습니다. 서비스 인스턴스 (SF 런타임에서 생성 된 WebApiService 클래스의 인스턴스)는 멤버 필드로 일부 임시 상태를 유지하며 내부 (스레드로부터 안전한) 메서드를 통해 상태를 노출합니다. WebApi 컨트롤러는 해당 상태에 액세스하기 위해 메소드를 호출해야합니다.StatelessService 인스턴스에 액세스하는 WebApi 컨트롤러

WebApiService.cs: 
----------------- 
internal sealed class WebApiService : StatelessService 
{ 
    private int _state; 

    internal int GetState() { return this._state; } 

ServiceController.cs: 
--------------------- 
public class ServiceController : ApiController 
{ 
    public async Task<IHttpActionResult> GetStateAsync() 
    { 
    // Here I'd like to grab somehow the WebApiService instance 
    // and call its GetState internal method. 

내 질문은 :

  1. 어떻게 컨트롤러는 WebApiService 인스턴스에 대한 참조를 얻을 수 있나요?

  2. WebApiService 인스턴스를 정적 ​​필드 (예 : WebAspiService 생성자)에 저장하는 것이 안전합니까?

+0

그래서이 권리를 갖자. 당신은 국적이없는 서비스에서 상태를 구현하고 있습니까? –

+0

예, 상태없는 서비스에서 일시적인 메모리 내 상태를 구현 중입니다! –

답변

1

서비스 인스턴스를 DI 컨테이너를 통해 컨트롤러에 대한 종속성으로 주입하십시오.

다음은 Unity를 사용하여 Katana에서 호스팅되는 웹 API의 예입니다. 그것은 상태 서비스입니다하지만 상태가없는 서비스에 대해 정확히 같은 방식으로 작동합니다 : https://github.com/Azure-Samples/service-fabric-dotnet-getting-started/tree/master/Services/WordCount/WordCount.Service

여기 Asp.Net 코어와 내장 된 의존성 주입 컨테이너 사용 예입니다 (상태도,하지만 같은 일 적용) : https://github.com/vturecek/service-fabric-xray/tree/master/src/xray.Data

+0

나는 Autofac을 사용하여 추천 한 DI 경로를 선택했습니다. 매력처럼 작동합니다. 감사합니다 .-) –

+0

첫 번째 링크는 지금 아무것도 가리키고 있지 않습니다. : - / – JoaoRibeiro

1

나는 DI 컨테이너를 사용할 수 있다고 생각합니다. 나는 simpleinjector을 추천 할 수 있지만 (같은 것을 할 수있는 많은 것들이있다.) simpleinjector는 요청과 웹 api 패키지 당 객체 수명 관리를 가지고있다. 상태 인스턴스를 컨테이너에 싱글 톤 (singleton)으로 넣고 컨트롤러에 삽입하면 스레드 안전 방법이되고 다중 스레드 웹 환경의 정적 필드에서 더 멀리 떨어져있게됩니다.

+0

감사합니다, 당신은 기본적으로 샘플에 대한 링크 때문에 내가 선택한 위의 허용 대답과 동일하다고 말합니다. 그럼에도 불구하고 스레딩 문제를 언급 해 주신 귀하의 답변에 감사드립니다. –

0

당신은 당신이 비 저장 서비스의 메소드를 호출하기 전에 컨트롤러의 상태 비 저장 서비스를 해결해야한다 :

public async Task<IHttpActionResult> GetStateAsync() 
{ 
    var proxyLocation = new ServiceUriBuilder("WebApiService"); 
    var svc = ServiceProxy.Create<IWebApiService>(proxyLocation.ToUri()); 
    return svc.GetState(); 
} 

당신은 다시 GetState 방법을 포함하는 인터페이스 IWebApiService을 작성해야합니다. WebApiService는이를 구현해야합니다. 기본적으로 WebApiService를 IWebApiService 인터페이스로 추상화해야합니다.

+2

나는 이것을 확실히 권장하지 않습니다. 이는 교차 서비스 원격 프로 시저 호출을위한 것입니다. 이것이 끝날 때까지는 서비스 인스턴스로 다시 네트워크 채널을 여는 것입니다. 즉, 메소드를 호출 할 때마다 호출을 직렬화하고, 원격 스택으로 모든 것을 전송하고, 직렬화 해제하고, 메소드를 호출하고, 결과를 serialize하고, 원격 스택으로 돌아가서 마지막으로 deserialize합니다. –

+0

@VaclavTurecek에 대한 설명 주셔서 감사합니다! 교차 서비스 원격 프로 시저 호출의 경우 종속성 (stateless services)을 (DI를 통해) 주입 할 수 있습니까? – alltej

+0

ServiceProxy를 사용하여 프록시 인스턴스 (대상 서비스 인터페이스의 형태를 가짐)를 생성하고이를 서비스 인스턴스에 직접 삽입 할 수 있습니다. 여기서 이점은 메서드를 호출하려는 대상 서비스의 인터페이스에 대해 서비스가 작동하고 있다는 것입니다. 그러나 프록시를 만들 때 파티션 키를 지정하기 때문에 대상 서비스가 분할되지 않은 경우에만 작동합니다.따라서 약간 더 나은 접근법은 IServiceProxyFactory를 삽입하여 프록시에서 서비스를 사용하는 것입니다 (단위 테스트를 위해 조롱 될 수도 있음). –

관련 문제