할 수 있습니 자동으로 호스트하는 모든 서비스를 사용합니다.구성할 때 사용하여 SelfHosting?

StackOverflow https://stackoverflow.com/questions/5993563

문제

나는 응용 프로그램을 작성해야하는 호스트는 여러 WCF 서비스입니다.의 강점 중 하나 WCF 구성 할 수있는 기능을 서비스하지 않고 다시 컴파일을 지정하여 설정합니다.config 파일에 있습니다.

할 때 스스로가 나타나지 않는 out-of-the-box 방법을 자동으로 호스트하는 서비스는 응용 프로그램에 있습니다.config 파일에 있습니다.내가 발견 이 질문 을 언급 가능한 해결책의 동적으로 서비스 열거 뉴스 관련 응용 프로그램입니다.config 런타임과 생성 ServiceHost 있습니다.

그러나 내 서비스,계약,그리고 호스팅 응용 프로그램은 모두에서 다른 어셈블리입니다.이렇 Type.GetType(string name) 을 실패하여 찾아 내는 서비스 유형(반환 null)기 때문에 정의에서 다른 어셈블리입니다.

할 수 있는 방법 안정적으로 호스트하는 모든 서비스는 응용 프로그램에 나와.config 파일을 동적으로(즉,지 않고,하드 코딩 new ServiceHost(typeof(MyService)) 내 셀프 호스팅 응용 프로그램?

참고:니다.config 를 사용하여 생성되었는"WCF 구성 편집기에서"Visual Studio2010.

참고:나의 기본 목표는 이것에 의해 몹니다.config 파일 그래서 거기에 단일 지점의 구성.나는 원하지 않는 이를 구성하는 별도의 위치에 있습니다.

편집:나를 읽을 수 있다.config file(참조 어),하지만 할 필요를 해결할 수 있 유형에 다른 어셈블리입니다.

편집:중 하나에 대한 답변을 아래에 나에게 메시지를 지정합니다 AssemblyQualifiedName 를 사용합니다.config 대한 기본 형식 이름입니다.이것을 얻을 수 있었다 주변 Type.GetType() 그러나 문제 ServiceHost.Open() 실패하고 지금 InvalidOperationException 에 관계 없이 내가 어떻게 달성하는 유형:

// Fails
string typeName = typeof(MyService).AssemblyQualifiedName;
Type myType = Type.GetType(typeName);
ServiceHost host = new ServiceHost(myType);
host.Open(); // throws InvalidOperationException

// Also fails
Type myType2 = typeof(MyService);
ServiceHost host2 = new ServiceHost(myType2);
host2.Open(); // throws InvalidOperationException

예외 정보:

Service 'SO.Example.MyService' has zero application (non-infrastructure) endpoints. This might be because no configuration file was found for your application, or because no service element matching the service name could be found in the configuration file, or because no endpoints were defined in the service element.

나 WCF 시도 일치하는 문자열에 대한 서비스 이름 때문 분석니다.config 파일을 내부적으로 합니다.

EDIT/답변:내가 무슨 일을 했었는 기본적으로 무엇이었을에서 대답이다.를 사용하는 대신 Type.GetType() 나는 나의 모든 서비스는에서 같은 어셈블리로 전환하도록:

// Get a reference to the assembly which contain all of the service implementations.
Assembly implementationAssembly = Assembly.GetAssembly(typeof(MyService));
...
// When loading the type for the service, load it from the implementing assembly.
Type implementation = implementationAssembly.GetType(serviceElement.Name);

다른 팁

    // get the <system.serviceModel> / <services> config section
    ServicesSection services = ConfigurationManager.GetSection("system.serviceModel/services") as ServicesSection;

    // get all classs
    var allTypes = AppDomain.CurrentDomain.GetAssemblies().ToList().SelectMany(s => s.GetTypes()).Where(t => t.IsClass == true);

    // enumerate over each <service> node
    foreach (ServiceElement service in services.Services)
    {
        Type serviceType = allTypes.SingleOrDefault(t => t.FullName == service.Name);
        if (serviceType == null)
        {
            continue;
        }

        ServiceHost serviceHost = new ServiceHost(serviceType);
        serviceHost.Open();
    }
.

다른 답변을 기반으로, ipp.config 에있는 서비스에 대한 모든 어셈블리를 검색하는 코드를 다음과 같이 확장했습니다.

는 확실히 해야 가능합니다!이 코드를 조각용으로 재단하고 여기에서 이동:

using System.Configuration;   // don't forget to add a reference to this assembly!

// get the <system.serviceModel> / <services> config section
ServicesSection services = ConfigurationManager.GetSection("system.serviceModel/services") as ServicesSection;

// enumerate over each <service> node
foreach(ServiceElement aService in services.Services)
{
    Console.WriteLine();
    Console.WriteLine("Name: {0} / Behavior: {1}", aService.Name, aService.BehaviorConfiguration);

    // enumerate over all endpoints for that service
    foreach (ServiceEndpointElement see in aService.Endpoints)
    {
        Console.WriteLine("\tEndpoint: Address = {0} / Binding = {1} / Contract = {2}", see.Address, see.Binding, see.Contract);
    }
}

이것을 지금 다만을 출력하고 정보-하지만 당신은 확실히 사용할 수 있습 이를 실제로 구축 서비스하는 호스트의 자신의 NT 서비스!

업데이트: ok,sorry,나는 당신의 가장 중요한 점은 사실은 실제 서비스는 다른 어셈블리입니다.

는 경우에,당신은 필요하여 부하를 동적으로 해당 어셈블리,필요에 따라 수 있습니다-당신이 예를들면"그냥 단순히 알고"무엇을 어셈블리를 로드하거나 당신 넣을 수 있으로 그들 모두의 특정 하위 디렉토리와 모든 어셈블리에서는 디렉토리,또는 당신은 단지 검사는 모든 어셈블리에서 동일한 위치 MyOwnServiceHost.exe 상주하고 확인을 찾으면 어떤 종류는 당신이 필요합니다.

이 파트는 서비스 유형을 찾기에서는 어셈블리지 않에 의해 처리됩 WCF 설정-당신이해야 할이 자신에 의하여,어떤 의미에게 가장 적습니다.

// find currently executing assembly
Assembly curr = Assembly.GetExecutingAssembly();

// get the directory where this app is running in
string currentLocation = Path.GetDirectoryName(curr.Location);

// find all assemblies inside that directory
string[] assemblies = Directory.GetFiles(currentLocation, "*.dll");

// enumerate over those assemblies
foreach (string assemblyName in assemblies)
{
   // load assembly just for inspection
   Assembly assemblyToInspect = Assembly.ReflectionOnlyLoadFrom(assemblyName);

   if (assemblyToInspect != null)
   {
      // find all types
      Type[] types = assemblyToInspect.GetTypes();

      // enumerate types and determine if this assembly contains any types of interest
      // you could e.g. put a "marker" interface on those (service implementation)
      // types of interest, or you could use a specific naming convention (all types
      // like "SomeThingOrAnotherService" - ending in "Service" - are your services)
      // or some kind of a lookup table (e.g. the list of types you need to find from
      // parsing the app.config file)
      foreach(Type ty in types)
      {
         // do something here
      }
   }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top