自定义的配置文件实现动态注入
一、前言
大家使用了很多依赖注入的组件,不懂得话可以搜索一下博客园相关的博文。这篇博文主要是介绍如何使用配置,通过自定义的的元素节点动态实现依赖注入。这里涉及了几个相关的类:ConfigurationSection,ConfigurationElementCollection和ConfigurationElement。
二、测试代码划分
简单给给大家看一下测试Demo
三、实现过程
1.配置文件
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<!--第一步-->
<!--configSections要定义最上面,定义configSections,name是对应下面元素名,type(类的位置,程序集)-->
<configSections>
<section name="serviceMappingsConfiguration"
type="UserDefinedConfiguration.Configuration.ServiceSetting, UserDefinedConfiguration, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</configSections>
<!--第二步,配置接口名和对应的接口实例位置-->
<serviceMappingsConfiguration>
<serviceMappings>
<serviceMapping interfaceName="IOrderService"
instanceName="UserDefinedConfiguration.Service.OrderService, UserDefinedConfiguration, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<serviceMapping interfaceName="IProductService"
instanceName="UserDefinedConfiguration.Service.ProductService, UserDefinedConfiguration, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</serviceMappings>
</serviceMappingsConfiguration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
2.创建一个类ServiceSetting,继承ConfigurationSection,定义一个节点集合属性ServiceMappingCollection
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UserDefinedConfiguration.Configuration
{
public class ServiceSetting : ConfigurationSection
{
[ConfigurationProperty("serviceMappings", IsDefaultCollection = true)] //声明,实例化配置属性
public ServiceMappingCollection ServiceMappings
{
get { return (ServiceMappingCollection)base["serviceMappings"]; }
}
}
}
3.创建的ServiceMappingCollection类继承ConfigurationElementCollection,重写ConfigurationElementCollection的方法
在ServiceMappingCollection中也用到了自己定义的ServiceMappingElement类。
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UserDefinedConfiguration.Configuration
{
public sealed class ServiceMappingCollection : ConfigurationElementCollection
{
//实例化一个新的元素(子节点)
protected override ConfigurationElement CreateNewElement()
{
return new ServiceMappingElement();
}
//获取节点的Key名字
protected override object GetElementKey(ConfigurationElement element)
{
return ((ServiceMappingElement)element).InterfaceName;
}
//配置节点集合类型
public override ConfigurationElementCollectionType CollectionType
{
get { return ConfigurationElementCollectionType.BasicMap; }
}
//子节点名
protected override string ElementName
{
get { return "serviceMapping"; }
}
public new ServiceMappingElement this[string interfaceName]
{
get {
return (ServiceMappingElement)BaseGet(interfaceName);
}
}
}
}
4.创建的ServiceMappingElement类继承ConfigurationElement,在ServiceMappingElement设置好和 配置文件定义节点serviceMapping的属性关系
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UserDefinedConfiguration.Configuration
{
//设置元素对应关系
public sealed class ServiceMappingElement : ConfigurationElement
{
[ConfigurationProperty("interfaceName",IsKey = true, IsRequired = true)] //这里指定了Key ,IsKey = true
public string InterfaceName
{
get { return (string)this["interfaceName"]; }
set { this["interfaceName"] = value; }
}
[ConfigurationProperty("instanceName", IsRequired = true)] //这里没指定Key
public string InstanceName
{
get { return (string)this["instanceName"]; }
set { this["instanceName"] = value; }
}
}
}
5.自定义的IProductService服务类已经它的实现
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UserDefinedConfiguration.IService
{
public interface IProductService
{
void GetProductByID(string id);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UserDefinedConfiguration.IService;
namespace UserDefinedConfiguration.Service
{
public class ProductService:IProductService
{
public void GetProductByID(string id)
{
Console.WriteLine("得到商品ID:"+id);
}
}
}
6.测试
通过(ServiceSetting)ConfigurationManager.GetSection("serviceMappingsConfiguration") 注册上面配置好的所有信息,并通过反射创建接口的实例,存入到缓存中,减少系统的压力
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UserDefinedConfiguration.Configuration;
using UserDefinedConfiguration.IService;
namespace Test
{
class Program
{
static void Main(string[] args)
{
IProductService productService = Program.GetService<IProductService>();
productService.GetProductByID("9527");
IOrderService orderService = Program.GetService<IOrderService>();
orderService.Create("1000");
Console.ReadKey();
}
private static Dictionary<string, object> dic = new Dictionary<string, object>();
public static TIService GetService<TIService>() where TIService : class
{
TIService service = default(TIService);
string interfaceName = typeof(TIService).Name;
if (!dic.ContainsKey(interfaceName))
{
//最重要的方法,初始化配置阶段所有信息
ServiceSetting settings = (ServiceSetting)ConfigurationManager.GetSection("serviceMappingsConfiguration");
//获取实例类型
Type instanceType = Type.GetType(settings.ServiceMappings[interfaceName].InstanceName);
//创建类型实例
service = Activator.CreateInstance(instanceType) as TIService;
dic.Add(interfaceName, service);
}
service = (TIService)dic[interfaceName];
return service;
}
}
}
运行结果:
作者:Kero小柯

浙公网安备 33010602011771号