C#Unity依赖注入
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C#Unity依赖注⼊
简介:
控制反转:我们向IOC容器发出获取⼀个对象实例的⼀个请求,IOC容器便把这个对象实例“注⼊”到我们的⼿中,在这个过程中你不是⼀个控制者⽽是⼀个请求者,依赖于容器提供给你的资源,控制权落到了容器⾝上。
这个过程就是控制反转。
依赖注⼊:我们向容器发出请求以后,获得这个对象实例的过程就叫依赖注⼊。
关于Ioc的框架有很多,⽐如astle Windsor、Unity、、StructureMap,我们这边使⽤微软提供的Unity做⽰例,你可以使⽤ Nuget 添加 Unity ,也可以引⽤Microsoft.Practices.Unity.dll和Microsoft.Practices.Unity.Configuration.dll,下⾯我们就⼀步⼀步的学习下 Unity依赖注⼊的详细使⽤。
⼀、使⽤ Nuget 添加 Unity
⼆、实现构造注⼊
添加⼀个接⼝和⼀个实现类,通过Main()⽅法调⽤测试。
///<summary>
///显⽰信息
///</summary>
public interface IUserDao
{
void Display(string mes);
}
class UserImpl : IUserService
{
public IUserDao IUserDao;
//构造函数设置值
public UserImpl(IUserDao UserDao)
{
IUserDao = UserDao;
}
///<summary>
///显⽰信息
///</summary>
///<param name="mes"></param>
public void Display(string mes)
{
IUserDao.Display(mes);
}
}
///<summary>
///显⽰信息
///</summary>
public interface IUserDao
{
void Display(string mes);
}
public class UserDaoImpl : IUserDao
{
public void Display(string mes)
{
Console.WriteLine(mes);
}
}
class Program
{
public IUserService IUserService { get; set; }
public static void Main(string[] args)
{
//创建容器
UnityContainer container = new UnityContainer();
//注册依赖对象
container.RegisterType<IUserService, UserImpl>();
container.RegisterType<IUserDao, UserDaoImpl>();
//返回调⽤者
IUserService IUser = container.Resolve<UserImpl>();
//执⾏
IUser.Display("王建");
Console.ReadLine();
}
}
点击运⾏,成功输出。
构造器注⼊
构造器注⼊(Constructor Injection):IoC容器会智能地选择选择和调⽤适合的构造函数以创建依赖的对象。
如果被选择的构造函数具有相应的参数,IoC容器在调⽤构造函数之前解析注册的依赖关系并⾃⾏获得相应参数对象。
RegisterType:可以看做是⾃来⽔⼚决定⽤什么作为⽔源,可以是⽔库或是地下⽔,我只要“注册”开关⼀下就⾏了。
Resolve:可以看做是⾃来⽔⼚要输送⽔的对象,可以是农村或是城市,我只要“控制”输出就⾏了。
三、属性注⼊
属性注⼊(Property Injection),就是通过 set 设值对对象进⾏设值,只需要在调⽤对象的上⾯加上[Dependency] 标记即可。
当依赖对象被容器初始化以后,会⾃动对该对象设值。
class UserImpl : IUserService
{
//只需要在对象成员前⾯加上[Dependency],
//就是把构造函数去掉,成员对象上⾯加[Dependency]注⼊
[Dependency]
public IUserDao IUserDao { get; set; }
//public UserImpl(IUserDao UserDao)
//{
// IUserDao = UserDao;
//}
///<summary>
///显⽰信息
///</summary>
///<param name="mes"></param>
public void Display(string mes)
{
IUserDao.Display(mes);
}
}
点击运⾏,实现的结果是⼀样的。
配置⽂件注册:
其实使⽤上⾯ RegisterType ⽅法进⾏注册,每次添加和删除⼀个注册都需要去修改代码和重新编译,这样不符合“⾼内聚、低耦合”的编程思想,所以我们可以采⽤配置⽂件的⽅式去注册,这样每次添加和修改注册就不需要去修改代码和重新发布了。
配置⽂件注册⽤UnityConfigurationSection 的 Configure加载配置⽂件注册。
代码(如果是控制台程序,配置写在App.config,如果是Web程序,就写在 Web.config):
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
Microsoft.Practices.Unity.Configuration"/>
</configSections>
<unity xmlns="/practces/2010/unity">
<containers>
<!--MyContainer为⾃定义名称只需要和调⽤时名称保持⼀致即可-->
<container name="MyContainer">
<!--type为对象的名称,mapTo为注⼊对象的名称写法为⽤逗号隔开两部分,⼀是类的全部,包括命名空间,⼆是程序集名称-->
<register type="ThreadDemo.Bll.IUserBll,ThreadDemo" mapTo="erBll,ThreadDemo">
<lifetime type="singleton"/>
</register>
<register type="ThreadDemo.Dal.IUserDal,ThreadDemo" mapTo="erDal,ThreadDemo"/>
</container>
</containers>
</unity>
<!--startup必须放在<configSections>节点下⾯,否则报错-->
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/>
</startup>
</configuration>
class Program
{
public IUserBll UserBll { get; set; }
public static void Main(string[] args)
{
//创建容器
//UnityContainer container = new UnityContainer();
//注册依赖对象
//container.RegisterType<IUserService, UserImpl>();
//container.RegisterType<IUserDao, UserDaoImpl>();
//返回调⽤者
//IUserService IUser = container.Resolve<UserImpl>();
//创建容器
UnityContainer container = new UnityContainer();
UnityConfigurationSection config = (UnityConfigurationSection)ConfigurationManager.GetSection(UnityConfigurationSection.SectionName);
//加载到容器
config.Configure(container, "MyContainer");
//返回调⽤者
IUserBll IUser = container.Resolve<IUserBll>();
//执⾏
IUser.Display("王建");
Console.ReadLine();
}
}
四、⽅法注⼊
⽅法注⼊和构造注⼊差不多,只不过把构造函数变成了⼀个普通的⽅法,在⽅法前⾯加[InjectionMethod] 属性。
namespace ThreadDemo.Bll.impl
{
public class UserBll : IUserBll
{
public IUserDal IDal;
///<summary>
///⽅法注⼊-加[InjectionMethod]属性
///</summary>
///<param name="IUserDal"></param>
[InjectionMethod]
public void SetInjection(IUserDal IUserDal)
{
IDal = IUserDal;
}
///<summary>
///显⽰信息
///</summary>
///<param name="mes"></param>
public void Display(string mes)
{
IDal.Display(mes);
}
}
}
这⼏种⽅法运⾏结果都是⼀样的。
五、Unity.MVC在Web中的应⽤
下⾯的例⼦是在Unity在Web项⽬中的使⽤:
1、安装Unity.MVC
2、在⽬录下会⽣成⼀个 BootStrapper.cs 的类⽂件,打开进⾏编辑(如果没有⽣成,⾃⼰创建,名称随意)。
namespace ShowWeatherWebUI
{
public class BootStrapper
{
///<summary>
///获取容器-注册依赖关系
///</summary>
///<returns></returns>
public static IUnityContainer Initialise()
{
var container = BuildUnityContainer();
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
return container;
}
///<summary>
///加载容器
///</summary>
///<returns></returns>
private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
}
///<summary>
///实施依赖注⼊
///</summary>
///<param name="container"></param>
private static void RegisterTypes(UnityContainer container)
{
//依赖关系可以选择代码形式,也可以⽤配置⽂件的形式
//UnityConfigurationSection config = (UnityConfigurationSection)ConfigurationManager.GetSection(UnityConfigurationSection.SectionName); //加载到容器
//config.Configure(container, "MyContainer");
container.RegisterType<IUerBll, UerBll>();
container.RegisterType<IUserDal, UserDal>();
}
}
}
3、在 Global.asax ⽂件中添加 BootStrapper.Initialise() 的⽅法。
因为Global.asax是应⽤程序启动的时候会执⾏,所以会去加载容器
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
//加载容器-注册依赖
BootStrapper.Initialise();
}
}
4、在Controller⾥调⽤,
在每个调⽤的接⼝添加 [Dependency] 属性即可,也就是属性输⼊,也可以采⽤构造函数注⼊和⽅法注⼊。
public class HomeController : Controller
{
[Dependency]
public IUerBll bll { get; set; }
public ActionResult Index()
{
bll.Display("王⽂建");
return View();
}
}。