惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Help Net Security
博客园 - Franky
GbyAI
GbyAI
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
爱范儿
爱范儿
IT之家
IT之家
酷 壳 – CoolShell
酷 壳 – CoolShell
aimingoo的专栏
aimingoo的专栏
博客园_首页
MongoDB | Blog
MongoDB | Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Recent Announcements
Recent Announcements
Scott Helme
Scott Helme
有赞技术团队
有赞技术团队
M
MIT News - Artificial intelligence
C
CERT Recently Published Vulnerability Notes
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Jina AI
Jina AI
F
Fortinet All Blogs
N
Netflix TechBlog - Medium
L
LangChain Blog
L
LINUX DO - 最新话题
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
H
Hacker News: Front Page
MyScale Blog
MyScale Blog
P
Palo Alto Networks Blog
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
AI
AI
T
Troy Hunt's Blog
Microsoft Azure Blog
Microsoft Azure Blog
阮一峰的网络日志
阮一峰的网络日志
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Vercel News
Vercel News
Microsoft Security Blog
Microsoft Security Blog
罗磊的独立博客
S
Secure Thoughts
大猫的无限游戏
大猫的无限游戏
博客园 - 叶小钗
人人都是产品经理
人人都是产品经理
Blog — PlanetScale
Blog — PlanetScale
博客园 - 司徒正美
Apple Machine Learning Research
Apple Machine Learning Research
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
S
Security @ Cisco Blogs
Cloudbric
Cloudbric
E
Exploit-DB.com RSS Feed
Attack and Defense Labs
Attack and Defense Labs

博客园 - oldkingsir

angularjs2 学习笔记(六) Form angularjs2 学习笔记(五) http服务 angularjs2 学习笔记(三) 服务 angularjs2 学习笔记(四) 路由 angularjs2 学习笔记(二) 组件 angularjs2 学习笔记(一) 开发环境搭建 Silverlight中利用MEF进行模块注入时注入错误问题分析 prism中ImportingConstructor构造注入时的参数匹配 解决Prism的EventAggregator的事件订阅错误 解决Prism中Region的GetView不起作用问题 Prism中在Region中注入匹配问题 想找一个专业一点的silverlight开发的群,谁知道啊! 在Prism中利用Region的对ContentControl的自动充填问题 silverlight 学习笔记 (九):Prism与MVVM模式在silverlight中的应用 由csdn搬家来此 silverlight 学习笔记 (七):Prism的第一个应用 vs2010中使用odac for .net的连接配置 Silverlight中对WCF RIA 的异步调用的同步处理解决办法 silverlight 学习笔记导航
silverlight 学习笔记 (八):Prism中MEF的初步认识
oldkingsir · 2012-02-23 · via 博客园 - oldkingsir

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

下面看实例,来自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 { getset; }
  }

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 { getset; }

    public void Send()
    {
      MessageSender("Processed");
    }
  }

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

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 { getset; }

    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 {getset;}

    public void Notify(string message) 
    {
      foreach(IMessageSender sender in Senders)
      {
        sender.Send(message);
      }
    } 
  }

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

public class Program : IPartImportsSatisfiedNotification
 {
    [ImportMany]
    public IEnumerable<IMessageSender> Senders {getset;}

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