学习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. Ubuntu中出现“Could not get lock /var/lib/dpkg/lock”的解决方法

    在运行Ubuntu安装软件,使用命令sudo  apt-get install时,有时会出现以下的错误: E: Could not get lock /var/lib/dpkg/lock - open ...

  2. 浅析Java泛型

    什么是泛型? 泛型是JDK 1.5的一项新特性,它的本质是参数化类型(Parameterized Type)的应用,也就是说所操作的数据类型被指定为一个参数,在用到的时候在指定具体的类型.这种参数类型 ...

  3. java8学习之自定义收集器实现

    在上次花了几个篇幅对Collector收集器的javadoc进行了详细的解读,其涉及到的文章有: http://www.cnblogs.com/webor2006/p/8311074.html htt ...

  4. JavaScript This 的六道坎

    鉴于this风骚的运作方式,对this的理解是永不过时的话题,本文试图通过将其大卸六块来钉住这个磨人的妖精. 首先 this is all about context. this说白了就是找大佬,找拥 ...

  5. k8sService资源

    一.service资源及其实现模型 通过规则定义出由多个pod对象组合而成的逻辑集合,以及访问这组pod的策略.service关联pod资源的规则要借助于标签选择器来完成 1.service资源概述 ...

  6. 【Python数据分析】用户通话行为分析

    主要工作: 1.对从网上营业厅拿到的用户数据.xls文件,通过Python的xlrd进行解析,计算用户的主叫被叫次数,通话时间,通话时段. 2.使用matplotlib画图包,将分析的结果直观的绘制出 ...

  7. 【UOJ#37】 [清华集训2014] 主旋律

    题目链接 题目描述 给定一张强联通图,求有多少种边的存在情况满足图依然强联通. \(n\leq15\) Sol 首先正难则反,考虑用总数减去不强联通的. 考虑一张不强联通的图,缩点后一定是一个 DAG ...

  8. django 路由层(反向解析)03

    目录 ORM表关系建立 Django请求生命周期流程图 urls.py 路由层 无名分组 有名分组 反向解析 无名分组的反向解析 有名分组的反向解析 以编辑功能为例 路由分发 名称空间 伪静态 虚拟环 ...

  9. border-box与content-box的区别

    ㈠box-sizing 属性 ⑴box-sizing 属性允许您以特定的方式定义匹配某个区域的特定元素. ⑵语法:box-sizing: content-box|border-box|inherit; ...

  10. Python Internet 模块

    Python Internet 模块 以下列出了 Python 网络编程的一些重要模块: 协议 功能用处 端口号 Python 模块 HTTP 网页访问 80 httplib, urllib, xml ...