/// <summary> /// 初始化服务容器 /// </summary> /// <param name="serviceName"> 服务约定名称 </param> /// <param name="serviceType"> 服务约定基类或接口类型 </param> /// <param name="typeComparer"> 比较2个类型服务的优先级 </param> /// <param name="logger"> 日志记录器 </param> /// <exception cref="ArgumentNullException"> /// <paramref name="serviceName" /> and <paramref name="serviceType" /> is all /// <see langword="null" />. /// </exception> /// <exception cref="OverflowException"> 匹配插件数量超过字典的最大容量 (<see cref="F:System.Int32.MaxValue" />)。 </exception> protected ServiceContainer(string serviceName, Type serviceType, IComparer<Type> typeComparer, TraceSource logger = null) { TypeComparer = typeComparer; _logger = logger ?? LogServices.Logger; _items = new ConcurrentDictionary<Type, ServiceItem>(); _logger?.Write(TraceEventType.Start, $"开始扫描服务插件 serviceName={serviceName},serviceType={serviceType}"); foreach (var p in MEF.PlugIns.GetPlugIns(serviceName, serviceType).OrderByDescending(p => p.Priority)) { var value = p.GetValue(serviceType); if (value == null) { continue; } var type = GetServiceType(p, value); if (type == null) { continue; } var item = new ServiceItem(this, type, value, p); item.MakeSystem(); //默认为系统插件 if (_items.TryAdd(type, item) == false) { _logger?.Write(TraceEventType.Verbose, $"服务插件({value.GetType().FullName})因优先级({p.Priority})过低被抛弃"); } else { _logger?.Write(TraceEventType.Verbose, $"服务插件({value.GetType().FullName}),优先级({p.Priority})装载完成"); } } _logger?.Write(TraceEventType.Stop, $"服务插件装载完成,有效服务 {Count} 个"); }
/// <summary> /// 拷贝当前服务项的所有属性,到新对象 /// </summary> /// <param name="item"> </param> /// <exception cref="ArgumentNullException"> <paramref name="item" /> is <see langword="null" />. </exception> /// <exception cref="FieldAccessException"> /// 在 .NET for Windows Store 应用程序 或 可移植类库 中,请改为捕获基类异常 /// <see cref="T:System.MemberAccessException" />。调用方没有访问此字段的权限。 /// </exception> internal void CopyTo(ServiceItem item) { if (item == null) { throw new ArgumentNullException(nameof(item)); } foreach (var field in typeof(ServiceItem).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { if (field.IsLiteral == false) { field.SetValue(item, field.GetValue(this)); } } }
/// <summary> /// 获取指定类型的服务对象。 /// </summary> /// <returns> /// <paramref name="serviceType" /> 类型的服务对象。- 或 -如果没有 <paramref name="serviceType" /> 类型的服务对象,则为 null。 /// </returns> /// <param name="serviceType"> 一个对象,它指定要获取的服务对象的类型。 </param> /// <exception cref="Exception"> 构造函数中传入的 value 为 <seealso cref="ServiceCreatorCallback" /> 类型,且执行中出现异常. </exception> /// <exception cref="ArgumentException"><see cref="serviceType"/> 为 <seealso cref="ServiceItem"/> 类型.</exception> public ServiceItem GetServiceItem(Type serviceType) { if (serviceType == typeof(ServiceItem)) { throw new ArgumentException($"{nameof(serviceType)}不能是{nameof(ServiceItem)}类型"); } var child = (Value as IServiceProvider)?.GetService(serviceType); //生成新的服务 if (child == null) { return null; } var item = new ServiceItem(Container, serviceType, child, PlugIn); if (IsSystem) //生成服务与当前服务(依赖服务)属性必须一致 { item.MakeSystem(); } PropertyChanged += item.ParentPropertyChanged; //当当前服务(依赖服务)发生属性变化时需要通知生成服务 return item; }