Unity IOC容器的基本使用
引入类库
类库名 | 作用 |
---|---|
Unity | 包含Unity容器和抽象库作为一个单独的包 |
Unity.Configuration | 配置文件,以配置文件的方式配置Unity容器 |
Unity Interception | AOP扩展 |
Unity.Interception.Configuration | AOP配置文件,以配置文件的方式提供AOP扩展 |
基本使用
测试类
public interface ICar
{
int Run();
}
public class Ford : ICar
{
private int _meter = 0;
public int Run()
{
return ++_meter;
}
}
public class BMW : ICar
{
private int _meter = 0;
public int Run()
{
return ++_meter;
}
}
public class Driver
{
private ICar _car = null;
public Driver(ICar car)
{
_car = car;
}
public void RunCar()
{
Console.WriteLine($"{_car.GetType().Name}:跑了{_car.Run()} 米 ");
}
}
代码方式
IUnityContainer container = new UnityContainer();
container.RegisterType<ICar,Ford>();
Driver driver = container.Resolve<Driver>();
driver.RunCar();
Console.Read();
配置文件方式
-
创建CfgFiles专门存放Unity.config
-
Unity.config的属性设置为始终复制
-
设置配置文件,包含了AOP的配置,相关的AOP源码会放在文章下方。
<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration"/>
</configSections>
<unity>
<sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration"/>
<containers>
<container name="aopContainer">
<register type="UnityTest.ICar,UnityTest" mapTo="UnityTest.BMW,UnityTest"/>
</container>
</containers>
</unity>
</configuration>
- 引入Unity容器
#region 引入Unity容器,这是一段固定写法 作用是读取当前应用程序运行目录下的Unity.Config配置文件,配置一个容器
//1. 初始化UnityContainer容器
IUnityContainer container = new UnityContainer();
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
//2. 开始读取配置文件
fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "CfgFiles\\Unity.Config");
Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
UnityConfigurationSection configSection = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
#endregion
//01 使用UnityConfigurationSection 配置(容器,名称)方法代替 配置容器 将容器和配置文件中的别名关联"
configSection.Configure(container, "aopContainer");
//02 通过容器创建对象
Driver driver = container.Resolve<Driver>();
//02 调用业务方法
driver.RunCar();
Console.Read();
生命周期管理
瞬时生命周期(TransientLifetimeManager)
瞬时生命周期,每次都是构造一个新的对象。
IUnityContainer container = new UnityContainer();
//以下两种注册,效果是一样的
//默认瞬时生命周期:每次都是构造一个新的
container.RegisterType<ICar, BMW>();
container.RegisterType<ICar, BMW>(new TransientLifetimeManager());
Driver drv = container.Resolve<Driver>();
配置文件
<register type="ICar" mapTo="BMW">
<lifetime type="transient" />
</register>
在配置文件中注册关系的时候更改一个生命周期管理器只需在
其中
1)type,生命期周期管理器的类型,可以选择Unity内置的,也可以使用自定义的,其中内置的生命周期管理器会有智能提示。
2)typeConverter,生命周期管理器转换类,用户自定义一个生命周期管理器的时候所创建一个转换器。
3)value,初始化生命周期管理器的值。
全局单例生命周期(SingletonLifetimeManager)
- 全局单例生命周期,全局只有一个该类型示例
- 非强制性,只有通过容器获取的才是单例。
- 项目中推荐使用容器单例
container.RegisterType<ICar, Ford>(new SingletonLifetimeManager());
ICar car = container.Resolve<ICar>();
ICar car1 = container.Resolve<ICar>();
Console.WriteLine(object.ReferenceEquals(car, car1));
<register type="UnityTest.ICar,UnityTest" mapTo="UnityTest.BMW,UnityTest">
<lifetime type="singleton" />
</register>
线程单例(PerThreadLifetimeManager)
同一个线程只有一个实例,不同线程就是不同实例。
应用场景:多线程处理事务,一个线程里面只有一个ORM,只有一个Context
container.RegisterType<ICar, Ford>(new PerThreadLifetimeManager());
ICar car1 = null;
ICar car2 = null;
ICar car3 = null;
Action act1 = new Action(()=>
{
car1 = container.Resolve<ICar>();
Console.WriteLine($"car1线程id={Thread.CurrentThread.ManagedThreadId}");
});
var result1 = act1.BeginInvoke(null,null);
Action act2 = new Action(()=>
{
car2 = container.Resolve<ICar>();
Console.WriteLine($"car2线程id={Thread.CurrentThread.ManagedThreadId}");
});
var result2 = act2.BeginInvoke(t=>
{
car3 = container.Resolve<ICar>();
Console.WriteLine($"car3线程id={Thread.CurrentThread.ManagedThreadId}");
Console.WriteLine($"object.ReferenceEquals(car1, car2):{object.ReferenceEquals(car2, car3)}");
},null);
act1.EndInvoke(result1);
act2.EndInvoke(result2);
Console.WriteLine($"object.ReferenceEquals(car1, car2):{object.ReferenceEquals(car1, car2)}");
其他生命周期
- HierarchicalLifetimeManager,分级容器单例,子容器的概念。
分层生命周期管理器,类似ContainerControlledLifetimeManager,是由UnityContainer管理,也是单例实例。与ContainerControlledLifetimeManager不同的是,这个生命周期管理器是分层的,因为Unity容器是可以嵌套的,所以这个生命周期管理器就是针对这种情况,当使用了这种生命周期管理器,父容器 和子容器所维护的对象生命周期是由各自的容器来管理。
-
PerResolveLifetimeManager,循环引用,不提倡使用,这种循环引用要尽量避免
原文地址:https://www.cnblogs.com/fishpond816/p/14494834.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。