定义服务抽象服务构建工厂,使之能够实现实现服务工厂族,针对不同的部署环境进行支持
///
/// 服务构建工厂接口
///
public interface IServiceFactory:IDisposable
{
///
/// 上下文环境
///
string Name { get; }
///
/// 获取一个服务的实例
///
///
///
T GetService
///
/// 根据配置中对应的名称获取服务的实例
///
///
/// 服务名称
///
T GetService
}
普通服务构建工厂,通过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
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
}
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 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
return Container.Current.Resolve
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实例
///
///
///
public static T GetService
#if DEBUG
if (!ValidateServiceInterface(typeof(T)))
throw new ArgumentException("服务接口必须有ServiceContractAttribute标注");
#endif
//return GetInstance
return GetService
}
#if License
static RempLicense lic = new RempLicense();
#endif
///
/// 根据服务在容器中的配置名称从服务容器中获取服务实例
///
///
/// 服务的名称
///
public static T GetService
#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
}
///
/// 创建一个工厂
///
/// 工厂名称
///
public static IServiceFactory CreateFactory(string name) {
if (Container.Current.IsRegistered
return Container.Current.Resolve
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
Initial();
try {
return this.contianer.Resolve
} 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
} else
Container.Current.RegisterType
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
return GetService
}
public T GetService
if (InnerContainer == null)
throw new ObjectDisposedException("ServiceFactory");
if (string.IsNullOrEmpty(name))
name = typeof(T).Name;
var obj = default(T);
lock (_sync) {
if (InnerContainer.IsRegistered
obj = InnerContainer.Resolve
var channel = obj as IClientChannel;
if (Validate(channel))
return obj;
}
}
obj = GetChannel
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
var obj = default(T);
lock (_sync) {
if (InnerContainer.IsRegistered
obj = InnerContainer.Resolve
var channel = obj as IClientChannel;
if (Validate(channel))
return obj;
var clientFactory = Container.Current.Resolve
if (ClientConfigHelper.IsEndPointExist(name)) {
obj = clientFactory.CreateClient
} 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
}
InnerContainer.RegisterInstance
}
return obj;
}
private LifetimeManager GetLifetimeManager() {
//return new ChannelLifeTimeManager();
if (string.IsNullOrEmpty(_lifetime))
return new ChannelLifeTimeManager();
if (Container.Current.IsRegistered
return Container.Current.Resolve
else
return new Microsoft.Practices.Unity.PerResolveLifetimeManager();
}
public void Dispose() {
InnerContainer.Dispose();
}
public static void StartService(string baseAdress,
IServiceFilter filter, IEventListener listener,
Action
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();
}
}