我在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;
抛出错误无效的强制转换异常。在运行时加载两个版本的ServiceContractAttribute。一个是动态加载的,另一个是GenerciServiceHost引用。我们无法删除服务引用,因为它会导致ServiceContractAttribute未定义复杂错误。
所有不同的服务实现都有不同的程序集,我们不想从genereicservicehost添加对所有程序集的引用,因为当任何服务行为发生变化时,它将导致重建genericservicehost。我们希望GenericServiceHost一直运行。
我们如何通过从程序集加载类型转换为程序集加载类型
来使其工作ServiceContractAttribute attribute = (ServiceContractAttribute)attributeType;
任何指针?
答案 0 :(得分:1)
Your architecture is flawed. It seems you have declared ServiceContractAttribute
multiple times, and then yes, the cast won't ever work, since each declaration produces a distinct type.
You have to decompose ServiceContractAttribute
into a separate assembly defining the common API between the host application and service assemblies, and share it across all services.