示例#1
0
 /// <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} 个");
 }
示例#2
0
 /// <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));
         }
     }
 }
示例#3
0
        /// <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;
        }