应用框架的设计与实现.net平台--跨领域组件--服务工厂

本文介绍了一种服务构建工厂的设计方案,该方案通过IOC容器加载服务层组件,支持不同部署环境。工厂可以根据服务类型和配置获取服务实例,并实现了服务实例的管理和销毁。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

定义服务抽象服务构建工厂,使之能够实现实现服务工厂族,针对不同的部署环境进行支持

  /// <summary>
    /// 服务构建工厂接口
    /// </summary>
public interface IServiceFactory:IDisposable
{
        /// <summary>
        /// 上下文环境
        /// </summary>
        string Name { get; }
        /// <summary>
        /// 获取一个服务的实例
        /// </summary>
        /// <typeparam name="T">服务类型</typeparam>
        /// <returns></returns>
        T GetService<T>() where T : class;


        /// <summary>
        /// 根据配置中对应的名称获取服务的实例
        /// </summary>
        /// <typeparam name="T">服务类型</typeparam>
        /// <param name="name">服务名称</param>
        /// <returns>服务实例</returns>
        T GetService<T>(string name) where T : class;
}


普通服务构建工厂,通过IOC容器,加载服务层组件:

/// <summary>
    /// 服务构建工厂
    /// </summary>
    public class ServiceFactory : IServiceFactory {


        private static Type __serviceAttributeType = typeof(System.ServiceModel.ServiceContractAttribute);


        private string _lifetime;
        private IUnityContainer contianer;
        static bool _loaded;
        static object _sync = new object();
        string path;


        static Lazy<string> defaultFactoryName = new Lazy<string>(() => {
 
                var q = AgileConfiguration.Current.Services.Cast<ServiceElement>();
                var item = q.FirstOrDefault(c => c.Assembly == "*");
                if (item != null)
                    return item.Factory;
                else
                    return string.Empty;
            });


        static string GetFactoryName<T>() {
            var q = AgileConfiguration.Current.Services.Cast<ServiceElement>();
            string name = typeof(T).Name;
            string assembly = typeof(T).Module.Name;
            assembly = assembly.Substring(0, assembly.Length - 4);


            var e = q.FirstOrDefault(c => c.Type == name && c.Assembly == assembly);
            if (e == null)
                e = q.FirstOrDefault(c => c.Assembly == assembly && (c.Type == "*" || string.IsNullOrEmpty(c.Type)));
            if (e != null)
                return e.Factory;
            else
                return defaultFactoryName.Value;
        }


        static IServiceFactory GetInstance<T>() {
            string factoryName = GetFactoryName<T>();
            if (string.IsNullOrEmpty(factoryName))
                return Container.Current.Resolve<IServiceFactory>();
            else
                return Container.Current.Resolve<IServiceFactory>(factoryName);
        }


        static ServiceFactory() {
            InitialFactories();
        }


        static void InitialFactories() {
            var items = AgileConfiguration.Current.ServiceFactories;
            var policy = new InterceptionBehavior<PolicyInjectionBehavior>();
            var intercptor = new Interceptor<TransparentProxyInterceptor>();


            foreach (ServiceFactoryElement item in items) {
                if (item.Name == "*" && Container.Current.IsRegistered<IServiceFactory>())
                    Trace.TraceWarning("ServiceFactory\tsevice factory " + item.Type + "has been ironed registed into container.");
                try {
                    var type = Type.GetType(item.Type, true);
                    if (item.Name != "*") {
                        Container.Current.RegisterType(typeof(IServiceFactory), type,
                            item.Name,
                            GetLifetimeManager(item.Lifetime),
                            new InjectionConstructor(item.Lifetime),policy,intercptor);
                    } else {
                        Container.Current.RegisterType(typeof(IServiceFactory),
                            type,
                            GetLifetimeManager(item.Lifetime),
                            new InjectionConstructor(item.Lifetime), policy, intercptor);
                    }
                } catch (Exception ex) {
                    throw new InvalidOperationException("regist serivce factory error,make sure configration is correct" + item.Type, ex); //) "注册服务工厂错误,请确认配置的类型是否正确:";
                }
            }
            if (!Container.Current.IsRegistered<IServiceFactory>())
                Container.Current.RegisterInstance<IServiceFactory>(new ServiceFactory(string.Empty),
                    new ContainerControlledLifetimeManager());


        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="lifetime"></param>
        public ServiceFactory(string lifetime) {
            _lifetime = lifetime;
            contianer = Container.Current;
        }


        void Initial() {
            if (contianer == null)
                throw new ObjectDisposedException("ServiceFactory");
            if (!_loaded) {
                lock (_sync) {
                    if (!_loaded) {
                        path = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory;
                        var dir = new DirectoryInfo(path);
                        var files = dir.GetFiles("*.services.???");
                        foreach (var file in files)
                            LoadAssemblyFromFile(file);


                    }
                }
                _loaded = true;
            }
        }


        private void LoadAssemblyFromFile(FileInfo file) {
            if (file.Extension == ".dll" || file.Extension == ".exe") {
                try {
                    Trace.TraceInformation("ServiceFactory\tload assembly " + file.Name);
                    var types = Assembly.LoadFile(file.FullName).GetTypes().Where(c => c.IsClass && !c.IsAbstract && c.IsPublic);
                    foreach (var item in types) {
                        RegistType(item);
                    }
                } catch {
                    Trace.TraceError("ServiceFactory\tload assembly failed " + file.Name);
                }
            }
        }


        private static LifetimeManager GetLifetimeManager(string lifetime) {
            if (string.IsNullOrEmpty(lifetime))
                lifetime = "default";
            if (Container.Current.IsRegistered<LifetimeManager>(lifetime))
                return Container.Current.Resolve<LifetimeManager>(lifetime);
            else
                return new Microsoft.Practices.Unity.PerResolveLifetimeManager();
        }


        private void RegistType(Type type) {
            var interfaces = type.GetInterfaces();
            var q = interfaces.Where(c => ValidateServiceInterface(c));
            if (q.Count() == 0) {
                Trace.TraceWarning("ServiceFactory\tcoud not find any service contract in type of " + type.FullName);
                return;
            }


            foreach (var item in q) {
                if (!this.contianer.IsRegistered(item))
                    this.contianer.RegisterType(item, type, GetLifetimeManager(_lifetime));
            }
        }


        private static bool ValidateServiceInterface(Type type) {
            if (!type.IsInterface)
                return false;
            return type.GetCustomAttributes(__serviceAttributeType, false).Length > 0;
        }


        /// <summary>
        /// 获取类型T实例
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <returns>T 的实例</returns>
        public static T GetService<T>() where T : class {
#if DEBUG
            if (!ValidateServiceInterface(typeof(T)))
                throw new ArgumentException("服务接口必须有ServiceContractAttribute标注");
#endif
            //return GetInstance<T>().GetService<T>();
            return GetService<T>(null);
        }


#if License
        static RempLicense lic = new RempLicense();
#endif


        /// <summary>
        /// 根据服务在容器中的配置名称从服务容器中获取服务实例
        /// </summary>
        /// <typeparam name="T">服务类型</typeparam>
        /// <param name="name">服务的名称</param>
        /// <returns>T的实例</returns>
        public static T GetService<T>(string name) where T : class {
#if DEBUG
            if (!ValidateServiceInterface(typeof(T)))
                throw new ArgumentException("服务接口必须有ServiceContractAttribute标注");
#endif


#if License
            if (System.Diagnostics.Debugger.IsAttached)
                throw new NotImplementedException();
            if (System.Web.HttpContext.Current != null)
                lic.Validate(typeof(T));
#endif


            //var serviceName = string.IsNullOrEmpty(name) ? typeof(T).Name : name;
            return GetInstance<T>().GetService<T>(name);
        }


        /// <summary>
        /// 创建一个工厂
        /// </summary>
        /// <param name="name">工厂名称</param>
        /// <returns><see cref="IServiceFactory"/></returns>
        public static IServiceFactory CreateFactory(string name) {
            if (Container.Current.IsRegistered<IServiceFactory>(name))
                return Container.Current.Resolve<IServiceFactory>(name);
            else
                return null;
        }


        #region IServiceFactory Members


        T IServiceFactory.GetService<T>() {
            Initial();
            try {
                return this.contianer.Resolve<T>();
            } catch (ResolutionFailedException rf) {
                throw new InvalidOperationException("构建服务对象错误,请确认'" + typeof(T).FullName + "'对应的实现Dll是否已经Copy到当前应用程序的bin目录或者运行目录:" + path, rf);
            }


        }


        T IServiceFactory.GetService<T>(string name) {
            Initial();
            try {
                return this.contianer.Resolve<T>(name);
            } catch (ResolutionFailedException re) {
                throw new InvalidOperationException("构建服务对象错误,请确认名称为" + "name" + "的对象'" + typeof(T).FullName + "'对应的实现Dll是否已经Copy到当前应用程序的bin目录或者运行目录中,并且已经注册", re);
            }
        }


        #endregion


        void IDisposable.Dispose() {


        }


        /// <summary>
        /// 
        /// </summary>
        public string Name {
            get {
                return "Default";
            }
        }


        /// <summary>
        /// 销毁服务
        /// </summary>
        /// <param name="obj"></param>
        public static void DestroyService(IDisposable obj) {
            DestroyService(obj, null);
        }


        internal static void DestroyService(IDisposable obj, IClientInstrumentationProvider instrumentation) {
            if (obj == null)
                return;
            var client = obj as System.ServiceModel.IClientChannel;
            if (client != null && client.State == System.ServiceModel.CommunicationState.Faulted) {
                client.Abort();
                if (instrumentation != null)
                    instrumentation.Faulted();
            } else {
                if (instrumentation != null)
                    instrumentation.Closed();
            }
            obj.Dispose();
        }


    }


WCF服务端,客户端服务工厂类,提供服务远程调用:

ublic class ServiceFactory : IServiceFactory {
        private static readonly IClientInstrumentationProvider _instrumentation;


        static ServiceFactory() {
            if (Container.Current.IsRegistered<LifetimeManager>()) {
                var lm = Container.Current.Resolve<LifetimeManager>();
                Container.Current.RegisterType<ClientFactory>(lm);
            } else
                Container.Current.RegisterType<ClientFactory>(new ContainerControlledLifetimeManager());
            if (Container.Current.IsRegistered<IClientInstrumentationProvider>()) {


                _instrumentation = Unity.GetClientInstrumentationProvider();
            }
        }


        string _lifetime;
        IUnityContainer InnerContainer {
            get {
                var val = _manager.GetValue() as IUnityContainer;
                if (val == null) {
                    val = new UnityContainer();
                    _manager.SetValue(val);
                }
                return val;
            }
        }
        static object _sync = new object();
        LifetimeManager _manager ;
        public ServiceFactory(string lifetime) {
            _lifetime = lifetime;//container = _manager.ge
            _manager = GetLifetimeManager();
        }


        public T GetService<T>() where T : class {
            return GetService<T>(string.Empty);
        }




        public T GetService<T>(string name) where T : class {
            if (InnerContainer == null)
                throw new ObjectDisposedException("ServiceFactory");


            if (string.IsNullOrEmpty(name))
                name = typeof(T).Name;
            var obj = default(T);
            lock (_sync) {
                if (InnerContainer.IsRegistered<T>(name)) {
                    obj = InnerContainer.Resolve<T>(name);
                    var channel = obj as IClientChannel;
                    if (Validate(channel))
                        return obj;
                }
            }


            obj = GetChannel<T>(name);


            return obj;
        }


        private bool Validate(IClientChannel channel) {
            if (channel == null)
                return false;
            try {
                if (channel.State > CommunicationState.Opened)
                    return false;
            } catch (ObjectDisposedException) {
                return false;
            }
            return true;
        }


        private T GetChannel<T>(string name) where T : class {
            var obj = default(T);
            lock (_sync) {
                if (InnerContainer.IsRegistered<T>(name))
                    obj = InnerContainer.Resolve<T>(name);
                var channel = obj as IClientChannel;
                if (Validate(channel))
                    return obj;


                var clientFactory = Container.Current.Resolve<ClientFactory>();
                if (ClientConfigHelper.IsEndPointExist(name)) {
                    obj = clientFactory.CreateClient<T>(name);
                } else {
                    var config = ClientConfigHelper.GetConfig<T>();
                    var address = config.GetAddress<T>();


                    if (string.IsNullOrWhiteSpace(address))
                        throw new ArgumentNullException(string.Format("没有找到EndPoint '{0}'对应的配置,请确认EndPoint是否已经正确配置", typeof(T).FullName));


                    var binding = RuntimeUnity.GetDefeaultBinding();


                    obj = clientFactory.CreateClient<T>(binding, new EndpointAddress(address), config.IsBidirectional);
                }
                InnerContainer.RegisterInstance<T>(name, obj, GetLifetimeManager());
            }


            return obj;
        }


        private LifetimeManager GetLifetimeManager() {


            //return new ChannelLifeTimeManager();
            if (string.IsNullOrEmpty(_lifetime))
                return new ChannelLifeTimeManager();
            if (Container.Current.IsRegistered<LifetimeManager>(_lifetime))
                return Container.Current.Resolve<LifetimeManager>(_lifetime);
            else
                return new Microsoft.Practices.Unity.PerResolveLifetimeManager();
        }


        public void Dispose() {
            InnerContainer.Dispose();
        }


        public static void StartService(string baseAdress,
            IServiceFilter filter, IEventListener listener,
            Action<ServiceHost> action, Action<Exception> error = null) {
            var packages = RuntimeUnity.GetServicePackages(baseAdress);
            foreach (var p in packages) {
                try {
                    var runner = new RemoteServiceRunner();
                    runner.Load(p);
                    var el = new EventListener();
                    el.Notify += (o, e) => { if (e.Type == "error")error(e.Exception); };
                    runner.Run(listener ?? el, filter ?? ServiceFilter.Empty);
                } catch (System.ServiceModel.CommunicationException ce) {
                    throw new NotSupportedException("请确认Net.Tcp Port Sharing Service等服务是否开启,以及服务器配置是否正确。", ce);
                } catch (Exception ex) {
                    if (error != null)
                        error(ex);
                }


            }
        }


        #region private methods




        #endregion


        public static void CloseService(IDisposable obj) {
            CloseService(obj, null);
        }


        internal static void CloseService(IDisposable obj, IClientInstrumentationProvider instrumentation) {
            if (instrumentation == null)
                instrumentation = _instrumentation;
            var client = obj as System.ServiceModel.IClientChannel;
            if (client == null)
                return;


            if (client.State == System.ServiceModel.CommunicationState.Faulted) {
                client.Abort();
                if (instrumentation != null)
                    instrumentation.Faulted();
            } else {
                client.Close();
                if (instrumentation != null)
                    instrumentation.Closed();
            }
        }


        public string Name {
            get {
                return "WCF";
            }
        }
        
        public void Teardown() {
            var lf = _manager as ChannelLifeTimeManager;
            if (lf == null)
                return;
            else
                lf.TearDown();
        }
    }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值