检查是否有任何类在assemby中定义了自定义属性,其中自定义属性和类都是动态加载的

本文关键字:自定义属性 动态 加载 assemby 任何类 是否 定义 检查 | 更新日期: 2023-09-27 18:26:46

我在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; }
        }
    }  

服务契约及其行为类使用ServceIdentifierAttribute进行装饰。

    [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的两个版本是在运行时加载的。一个是动态加载的,另一个是通过GenericServiceHost引用加载的。我们无法删除服务引用,因为它将导致ServiceContractAttribute未定义的复杂错误。

所有不同的服务实现都将有一个不同的程序集,我们不想添加对genericservicehost中所有程序集的引用,因为当任何服务行为发生变化时,这将导致重建genericservicehost。我们希望GenericServiceHost始终运行。

我们如何通过从组件加载类型转换为组件加载类型来实现这一点

ServiceContractAttribute attribute =  (ServiceContractAttribute)attributeType;

有指针吗?

检查是否有任何类在assemby中定义了自定义属性,其中自定义属性和类都是动态加载的

您的体系结构存在缺陷。您似乎已经多次声明ServiceContractAttribute,然后是的,强制转换永远不会工作,因为每个声明都会产生一个不同的类型。

您必须将ServiceContractAttribute分解为一个单独的程序集,定义主机应用程序和服务程序集之间的公共API,并在所有服务之间共享它。