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

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

  ///


    /// 服务构建工厂接口
    ///

public interface IServiceFactory:IDisposable
{
        ///
        /// 上下文环境
        ///

        string Name { get; }
        ///
        /// 获取一个服务的实例
        ///

        /// 服务类型
        ///
        T GetService() where T : class;


        ///
        /// 根据配置中对应的名称获取服务的实例
        ///

        /// 服务类型
        /// 服务名称
        /// 服务实例
        T GetService(string name) where T : class;
}


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

///


    /// 服务构建工厂
    ///

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


        static string GetFactoryName() {
            var q = AgileConfiguration.Current.Services.Cast();
            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() {
            string factoryName = GetFactoryName();
            if (string.IsNullOrEmpty(factoryName))
                return Container.Current.Resolve();
            else
                return Container.Current.Resolve(factoryName);
        }


        static ServiceFactory() {
            InitialFactories();
        }


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


            foreach (ServiceFactoryElement item in items) {
                if (item.Name == "*" && Container.Current.IsRegistered())
                    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())
                Container.Current.RegisterInstance(new ServiceFactory(string.Empty),
                    new ContainerControlledLifetimeManager());


        }


        ///
        /// 
        ///

        ///
        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(lifetime))
                return Container.Current.Resolve(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;
        }


        ///
        /// 获取类型T实例
        ///

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


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


        ///
        /// 根据服务在容器中的配置名称从服务容器中获取服务实例
        ///

        /// 服务类型
        /// 服务的名称
        /// T的实例
        public static T GetService(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().GetService(name);
        }


        ///
        /// 创建一个工厂
        ///

        /// 工厂名称
        ///
        public static IServiceFactory CreateFactory(string name) {
            if (Container.Current.IsRegistered(name))
                return Container.Current.Resolve(name);
            else
                return null;
        }


        #region IServiceFactory Members


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


        }


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


        #endregion


        void IDisposable.Dispose() {


        }


        ///
        /// 
        ///

        public string Name {
            get {
                return "Default";
            }
        }


        ///
        /// 销毁服务
        ///

        ///
        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()) {
                var lm = Container.Current.Resolve();
                Container.Current.RegisterType(lm);
            } else
                Container.Current.RegisterType(new ContainerControlledLifetimeManager());
            if (Container.Current.IsRegistered()) {


                _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() where T : class {
            return GetService(string.Empty);
        }




        public T GetService(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(name)) {
                    obj = InnerContainer.Resolve(name);
                    var channel = obj as IClientChannel;
                    if (Validate(channel))
                        return obj;
                }
            }


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


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


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


                    var binding = RuntimeUnity.GetDefeaultBinding();


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


            return obj;
        }


        private LifetimeManager GetLifetimeManager() {


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


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


        public static void StartService(string baseAdress,
            IServiceFilter filter, IEventListener listener,
            Action action, Action 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();
        }
    }



你可能感兴趣的:(asp.net,框架设计,.net,framework,WCF,IOC,Unity,服务工厂)