博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
silverlight 学习笔记 (八):Prism中MEF的初步认识
阅读量:6956 次
发布时间:2019-06-27

本文共 3393 字,大约阅读时间需要 11 分钟。

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

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

2011-04-27 15h52_04

 

 

 

 

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中指定名称则按名称进行匹配。强烈推荐使用契约名称进行匹配,契约名称可加入命名空间,这样匹配更加准确方便。

下面看实例,来自

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、契约可采用字符串进行标注

 

ExpandedBlockStart.gif
View Code
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中的,否则将会出现无法匹配的异常。

 

转载于:https://www.cnblogs.com/oldkingsir/archive/2012/02/23/2365624.html

你可能感兴趣的文章
Linux查看文件夹大小
查看>>
系统集成项目管理工程师整理资料
查看>>
writexml方法:
查看>>
AutoLayout经常用到的一些布局(含StackView)
查看>>
HLG 1541 集合划分【01背包】
查看>>
Java IO 详解
查看>>
php生成随机密码的几种方法
查看>>
c#编程模仿的1stopt界面
查看>>
Castle ActiveRecord的一对多问题
查看>>
移山亦可有道 ——读《移山之道》
查看>>
python使用windows注册表
查看>>
MySQL5.6.13安装步骤(Windows7 64位)札记 1
查看>>
使用 nginx + thin 的配置启动 rails server
查看>>
服务器用户登录记录
查看>>
Centos6.0使用第三方YUM源(EPEL,RPMForge,RPMFusion)
查看>>
PHP RSA加解密示例(转)
查看>>
centos7如何添加开机启动服务/脚本
查看>>
翻转句子中单词的顺序
查看>>
[LeetCode]题解(python):030-Substring with Concatenation of All Words
查看>>
C#实战-圆半径
查看>>