Unity容器依赖注入之属性注入使用备忘

Unity容器依赖注入之属性注入使用备忘

Unity容器依赖注入之属性注入使用备忘

——独立观察员 2018.08.18

最近在做我的毛坯项目”笔记扩展“,使用了WPF的MVVM模式,使用了Prism框架的一些功能,还没有使用依赖注入功能,于是打算尝试一下。

Prism框架官方支持Unity 和 MEF 两种 DI 容器,也就是官方实现了这两种容器的初始化配置等,当然你也可以使用其他的容器,只不过需要自己配置而已。Unity是微软团队Practices开发的,目前已转为社区维护,代码托管于GitHub。

Unity容器支持三种依赖注入方式:构造器注入 (Constructor Injection)、属性注入 (Property Injection),以及方法调用注入 (Method Call Injection)。本文主要讨论属性注入方式。

本人认为,依赖注入的好处,除了老生常谈的方便切换依赖项的实现外,还有就是可以方便地传值,有点像是全局变量的感觉。当然,这一点应该是要设置容器内使用单例模式。本文主要展示这方面的用法,有不对的地方欢迎指正。

好了,废话少说,Let’s go!

 

1、建立模型

 

首先,新建一个模型类的接口和其默认实现:

namespace Note.Models
{
    public interface IModifyConfigModel
    {
        string Key { get; set; }

        string Value { get; set; }
    }

    public class ModifyConfigModel : IModifyConfigModel
    {
        public string Key { get; set; }

        public string Value { get; set; }
    }
}

 

2、注册类型

 

然后我们打开Bootstrapper.cs文件,这个是Prism的启动类,可以通过让它继承哪个类,来决定使用哪个容器:

%title插图%num

这里我们继承的是UnityBootstrapper类,也就是说我们使用的是Unity容器。

 

UnityBoostrapper类做了很多初始化工作,其中,在ConfigureContainer方法中注册了很多类型,使用的是RegisterTypeIfMissing方法:

%title插图%num

 

所以,如果我们要注册自己的类型,就需要在Bootstrapper类中覆写ConfigureContainer方法:

protected override void ConfigureContainer()
{
	base.ConfigureContainer();

	RegisterTypeIfMissing(typeof(IModifyConfigModel), typeof(ModifyConfigModel), true);
}

 

同样使用 RegisterTypeIfMissing 方法,第一个参数传递接口类型,第二个参数传递实现类型,第三个参数指定是否使用单例模式。

 

下面来看看RegisterTypeIfMissing方法是怎样的:

%title插图%num

 

其中Container就是Unity的容器对象,如果不是使用Prism框架而是直接使用Unity的话,需要自己初始化这个对象。

然后其内部是使用Container的RegisterType方法来注册类型的。

 

3、存数据

 

注册好类型之后,我们就可以使用了。

属性注入的语法是使用Dependency特性,我们在ViewModel中添加一个属性:

[Dependency]
public IModifyConfigModel ModifyConfigModel { get; set; }

 

然后就可以对该对象的属性进行赋值了,不需要创建该对象,因为容器会代劳的:

ModifyConfigModel.Key = nameof(DbPath);
ModifyConfigModel.Value = DbPath;
ConfigManager.SetValueTestIoc();

 

赋的值是什么不用管,其中第三行的方法中使用了这些值,在另一个类中。为什么舍近求远?只是为了测试。

 

4、取数据

 

上面提到的方法如下:

//[Dependency]
//public static IModifyConfigModel ModifyConfigModel { get; set; }

public static bool SetValueTestIoc()
{
	//return SetValue(ModifyConfigModel.Key, ModifyConfigModel.Value);

	IModifyConfigModel modifyConfigModel = 
		ServiceLocator.Current.GetInstance<IModifyConfigModel>();
	return SetValue(modifyConfigModel.Key, modifyConfigModel.Value);
}

 

其中注释掉的部分我们称之为”方式一”,未注释的部分自然就是”方式二”了。

 

通常是使用方式一的,只要像这样声明同样的依赖注入属性,就可以取得里面的值。但是这种方式有的时候会失效,比如这里的ModifyConfigModel就为null。听说是生命周期的原因,我也没有去深究,因为我们可以使用方式二。

 

方式二使用了ServiceLocator来获取实例,可以完美达到预期效果。

 

最后提一下,ServiceLocator 的命名空间为Microsoft.Practices.ServiceLocation,Unity的命名空间为Microsoft.Practices.Unity,感兴趣的朋友可以自行探索其中的异同点。

 

5、参考

 

(1)《Microsoft.Practices.Unity 入门 – 在 delphi 路上 – 博客园

(2)《Prism 5 程序初始化过程 – Andy Ho – 博客园

原创文章,转载请注明: 转载自 独立观察员(dlgcy.com)

本文链接地址: [Unity容器依赖注入之属性注入使用备忘](https://dlgcy.com/unity-dependency/)

关注微信公众号 独立观察员博客(DLGCY_BLOG) 第一时间获取最新文章

%title插图%num

4条评论

四大名著情商课 发布于14:25 - 2018年10月11日

不错顶一个

ZZZZZZZ 发布于14:04 - 2018年9月21日

setvalue是哪里的呢

    独立观察员 发布于11:23 - 2018年9月22日

    自定义的赋值方法,不是重点,就没有体现

2018年稳妥赚钱项目 发布于22:39 - 2018年9月2日

不错顶一个

发表评论