学习Prism一定要掌握依赖注入的应用,只有了解了Prism的依赖注入才能更好的使用Prism提升应用开发的架构。

首先说明Prism依赖注入有两种方式及MEF和Unity ,在Prism中是两个没有关联的dll。我倾向于使用MEF,下面学习下MEF在Silverlight中的具体实现。先看MEF实现图示

 

1、Catalog(目录):为了发现可用于组合容器的部件,组合容器将使用“Catalog”。目录是一个对象,通过它发现可用部件,MEF 提供了用于从提供的类型、程序集或磁盘路径创建Catalog

2、Compose(组合):在MEF中,容器将导入与导出匹配的这一过程我们称之为组合,部件由 MEF 组合,MEF 将部件实例化,然后使导出程序与导入程序相匹配。

3、Part(部件):通过 MEF,应用程序可以通过部件的元数据来发现并检查部件,而不用实例化部件,或者甚至不用加载部件的程序集。在部件中可以指定1个或多个Export和Import。

4、Export(导出):在MEF中通过在类或属性中添加Export属性标签表明该对象能够被其他部件引入。

5、Import(导入):是通过向Container申请导入满足条件的对象实例。

在Import时需要遵循Export契约,否则导入将会失败。

按照MEF的约定,任何一个类或者是接口的实现都可以通过[System.ComponentModel.Composition.Export] 属性将其他定义组合部件(Composable Parts),在任何需要导入组合部件的地方都可以通过在特定的组合部件对象属性上使用 [System.ComponentModel.Composition.Import ]实现部件的组合,两者之间通过契约(Contracts)进行 通信。

在MEF中所有组合都需要匹配契约,契约可以是一个字符串或和类型,每一个Export都需要声明一个契约,同样每一个Import都可以定义相同的契约进行匹配。缺省情况下会按照type进行匹配。如果在Export中指定名称则按名称进行匹配。强烈推荐使用契约名称进行匹配,契约名称可加入命名空间,这样匹配更加准确方便。

下面看实例,来自http://mef.codeplex.com/

1、对象注入

[Export]

public class SomeComposablePart {  ...}

 2、属性注入

public class Configuration
{
[Export("Timeout")]
public int Timeout
{
get { return int.Parse(ConfigurationManager.AppSettings["Timeout"]); }
}
}
[Export]
public class UsesTimeout
{
[Import("Timeout")]
public int Timeout { get; set; }
}

3、方法注入 【名字区分】

public class MessageSender
{
[Export(typeof(Action<string>))]
public void Send(string message)
{
Console.WriteLine(message);
}
} [Export]
public class Processor
{
[Import(typeof(Action<string>))]
public Action<string> MessageSender { get; set; } public void Send()
{
MessageSender("Processed");
}
}

4、契约可采用字符串进行标注

public class MessageSender
{
[Export("MessageSender")]
public void Send(string message)
{
Console.WriteLine(message);
}
} [Export]
public class Processor
{
[Import("MessageSender")]
public Action<string> MessageSender { get; set; } public void Send()
{
MessageSender("Processed");
}
}

5、继承注入,即在基类或借口中定义契约,其子类自动应用其契约

[InheritedExport]
public interface ILogger {
void Log(string message);
} public class Logger : ILogger {
public void Log(string message);
}

 6、构造注入

class Program
{
[ImportingConstructor]
public Program(IMessageSender messageSender)
{
...
}
}

7、选项注入

[Export]
public class OrderController {
private ILogger _logger; [ImportingConstructor]
public OrderController([Import(AllowDefault=true)] ILogger logger) {
if(logger == null)
logger = new DefaultLogger();
_logger = logger;
}
}

8、集合注入 

public class Notifier
{
[ImportMany(AllowRecomposition=true)]
public IEnumerable<IMessageSender> Senders {get; set;} public void Notify(string message)
{
foreach(IMessageSender sender in Senders)
{
sender.Send(message);
}
}
}

9、为了保障一个对象的某些属性能够被及时实例化,可使用IPartImportsSatisfiedNotification

public class Program : IPartImportsSatisfiedNotification
{
[ImportMany]
public IEnumerable<IMessageSender> Senders {get; set;} public void OnImportsSatisfied()
{
// when this is called, all imports that could be satisfied have been satisfied.
}
}

10、MEF注入共享模式分为NoShared,Shared,Any三种,简单讲就是NoShared意味着每个调用者就将创建一个新的实例,而Shared将会为每一个调用者提供一个唯一的静态实例(也就是说单态)

[Export("UserManageViewModel")]
[PartCreationPolicy(CreationPolicy.Shared)]
public class UserManageViewModel:MyViewModelBase
{
....
}

通过以上介绍基本说明了MEF的注入模式,在实际应用中最重要的也常被忽视的可能就是契约的定义上,如果在类中标示了[Export(typeof(...))]而在引用时使用了[Import["..."]可能会导致无法匹配,另外说明的是所有的部件一定是要被加载到Container中的,否则将会出现无法匹配的异常。

WPF prism 类、属性和方法的导入和导出的更多相关文章

  1. python 类属性与方法

    Python 类属性与方法 标签(空格分隔): Python Python的访问限制 Python支持面向对象,其对属性的权限控制通过属性名来实现,如果一个属性有双下划线开头(__),该属性就无法被外 ...

  2. python装饰器、继承、元类、mixin,四种給类动态添加类属性和方法的方式(一)

    介绍装饰器.继承.元类.mixin,四种給类动态添加类属性和方法的方式 有时候需要給类添加额外的东西,有些东西很频繁,每个类都需要,如果不想反复的复制粘贴到每个类,可以动态添加. # coding=u ...

  3. python从入门到大神---1、初始化实例、类属性、方法

    python从入门到大神---1.初始化实例.类属性.方法 一.总结 一句话总结: 方法不加括号是代码段:感觉python方法和js,php很类似,不加括号是代码段,加括号变成方法,比如f,f() 1 ...

  4. python干货-类属性和方法,类的方法重写

    类属性与方法 类的私有属性 __private_attrs: 两个下划线开头,表明为私有,外部不可用,内部使用时self.__private_attrs. 类的方法 在类的内部,使用 def 关键字来 ...

  5. Python全栈开发之7、面向对象编程进阶-类属性和方法、异常处理和反射

    一.类的属性 1.@property属性 作用就是通过@property把一个方法变成一个静态属性 class Room: def __init__(self,name,length,width,he ...

  6. GDI+ —— Tcanvas 类属性及方法.......

    delphi TCanvas类 类关系   TObject-> TPersistent   对那些作图对象,可使用TCanvas对象作为画布.标准的window控件,例如编辑控件和列表框控件,当 ...

  7. python类的使用(类定义,构造器,类属性,方法)

    注:这里只描述使用方法,具体类的概念长篇大论就不要为难我这个懒人了. 总之一句话编程语言只是一个工具,会用就行,好用就行.打破砂锅问到底,我觉得有必要研究一下C,汇编,电子链路等. class clt ...

  8. TCanvas 类属性及方法

    delphi TCanvas类 类关系   TObject-> TPersistent   对那些作图对象,可使用TCanvas对象作为画布.标准的window控件,例如编辑控件和列表框控件,当 ...

  9. Python 进阶_OOP 面向对象编程_类属性和方法

    目录 目录 类属性 调用类属性 查看类属性 特殊的类属性 类方法 真构造器 __new__ 类属性 在理解类属性之前要先搞清楚 实例属性 和 函数属性 之间的区别: 1. 实例属性:指的是实例化类对象 ...

随机推荐

  1. linux命令详解——vim

    显示行号:命令模式下set nu 定位到指定行: 命令模式下,:n   比如想到第2行,:2 编辑模式下,ngg  比如想到第5行 5gg(或者5G) 打开文件定位到指定行   vim  +n  te ...

  2. 终极之战:Linux & Windows

    1.开源 当你买了一辆车,但你看不到引擎盖下面是什么?当你使用Windows驱动系统时就是如此.但是,相比之下,Linux完全是一个开源项目.你可以看看Linux操作系统的源代码,这是一个优点.Lin ...

  3. epoll机制和简述

    在linux的网络编程中,很长的时间都在使用select来做事件触发.在linux新的内核中,有了一种替换它的机制,就是epoll.相比于select,epoll最大的好处在于它不会随着监听fd数目的 ...

  4. openstack Rocky系列之keystone:(二)keystone中API注册

    主要说一下initialize_application中的application_factory def loadapp(): app = application.application_factor ...

  5. PhpStorm中如何使用database工具,详细操作方法

    1.简介:   PhpStorm是一个轻量级且便捷的PHP IDE,其提供的智能代码补全,快速导航以及即时错误检查等功能大大提高了编码效率.它以其独特的开发便利性,短时间内赢得了大量PHPer的青睐. ...

  6. java8学习之流的短路与并发流

    并发流: 从api的角度来看,其实跟咱们之前一直在用的stream()方式差不多,但是底层是有明显的不同,所以这里初步先对并发流有一个基本的认识, 说到串行与并行,最直观的感受就是效率的不同,所以下面 ...

  7. AWR报告提取方法

    AWR报告提取方法 关键字 AWR报告 内容描述 AWR报告的提取方法 涉及设备 oracle 10g 操作说明 [问题现象描述] 现场提取AWR报告 [分析结论及解决方案] Awr报告生成方法 进入 ...

  8. Centos7——docker持久化存储和卷间状态共享(笔记)

    docker持久化存储和卷间状态共享(笔记)  本章介绍 存储卷的介绍 存储卷的两种类型 宿主机好额容器之间如何共享数据 容器之间如何共享数据 存储卷的声明周期 存储卷之间的数据管理和控制模式 就像在 ...

  9. 【NOIP2017提高A组模拟9.5】心灵治愈

    题目 好吧,我表示比赛时完全看不懂题目 题目解释 良心的出题人为一道两三句可以讲清楚的题目,又写了一大坨恶心的解释. 容斥 其实题目就是有个数组a[1~n+1],已知a[n+1]=m,1<=a[ ...

  10. js-10s倒计时后关闭窗口

    效果: html: <h1 id="h1">10s后关闭窗口</h1> <a id="a1">启动</a> js ...