2015-12-14 3 views
0

Я работаю в wcf-сервисах, где службы хоста на случайных портах динамически. Сервисный контракт и сборка поведения службы загружаются динамически, и все типы проверяются на соответствие имени службы и ее версии. Та же служба может работать на разных версиях. Чтобы отличать версии сервиса, мы создали собственный атрибут ServiceIdentifierAttribute.проверка, если какой-либо класс имеет настраиваемый атрибут, определенный в сборке, где динамический динамический динамический динамический динамический динамический режим

public class ServiceIdentifierAttribute : Attribute 
    { 
     private string _name; 
     public string Name 
     { 
      get { return _name; } 
      set { _name = value; } 
     } 

     private string _version; 
     public string Version 
     { 
      get { return _version; } 
      set { _version = value; } 
     } 
    } 

Сервисный контракт и его класс поведения украшены атрибутом SerivceIdentifierAttribute.

[ServiceContract(Name = "ABCServicesV0.0.0.0")] 
    [ServiceIdentifierAttribute(Name = "ABCServicesV0.0.0.0", Version = "V0.0.0.0")] 
    public interface IABCService 
    { 
    } 

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple, Name = "ABCServicesV0.0.0.0")] 
    public class ABCService : IABCService 
    {} 

Сервисный контракт, атрибут определяется в одной сборке и выполнении Услуг в другом. У нас есть консольное приложение GenericSericeHost, которое динамически размещает службы, загружая обе сборки. Нам нужно искать все типы и получать тип контракта на обслуживание из сборки.

private static bool SeachForServiceContractAttribute(Type type, String serviceIdentifier) 
     { 
      if (type.IsDefined(typeof(ServiceContractAttribute), false)) 
      { 
       var attributeTypes = type.GetCustomAttributes(); 
       foreach (var attributeType in attributeTypes) 
       { 
        try 
        { 
         ServiceContractAttribute attribute = (ServiceContractAttribute)attributeType; 
         if (attribute != null && !string.IsNullOrEmpty(attribute.Name) && attribute.Name.Equals(serviceIdentifier)) 
          return true; 
        } 
        catch (Exception ex) 
        { 
         Console.Write(ex.Message); 
        } 
       } 
      } 
     return false; 
     } 

GenericServiceHost имеет ссылку на сборку ServiceContract. Во время выполнения ServiceContractAttribute attribute = (ServiceContractAttribute)attributeType; is throwing error Неверное исключение литья. Поскольку две версии ServiceContractAttribute загружаются во время выполнения. Один загружается динамически, а другой - по ссылке GenerciServiceHost. Мы не можем удалить ссылку на службу, так как это приведет к ошибке определения несовместимости ServiceContractAttribute.

Все различные сервисные реализации будут иметь другую сборку, и мы не хотим добавлять ссылку на все сборки из genereicservicehost, так как это приведет к восстановлению genericservicehost при изменении любого поведения службы. Мы хотим, чтобы GenericServiceHost работал постоянно.

Как мы можем сделать эту работу путем литья из сборки загруженного типа для сборки загружен тип

ServiceContractAttribute attribute = (ServiceContractAttribute)attributeType; 

Любой указатель?

+0

Зачем его загружать дважды? Атрибут - это объект инфраструктуры, и на сборку следует просто ссылаться. Загрузка других вещей динамически или нет не должна влиять на эту сборку. – Ralf

ответ

1

Недостаток вашей архитектуры. Кажется, вы неоднократно заявляли ServiceContractAttribute, а затем да, литой не будет когда-либо работают, так как каждая декларация производит различный тип.

Вы должны разложить ServiceContractAttribute на отдельную сборку, определяющую общий API между хост-приложением и узлами обслуживания, и делиться им по всем службам.

Смежные вопросы