一个基于MEF的可拓展的WPF Host程序 (0)

从本文开始我们将介绍一个基于MEF的可拓展的WPF程序。这将会是一个比较长的系列性文章,我也不知道会写多长:)。作为系列的第一篇,我们先介绍一下我们到底要做什么吧。我想做过界面的程序员都知道,界面做起来很麻烦,既费时又费力,而且并不一定讨用户喜欢,而且发布起来很麻烦。我想,这也是为什么这些年来网页技术发展得这么红火吧。不知道是不是自己很怀旧,还是实在不习惯总使用浏览器,本人还是很喜欢用desktop application。而且,我们不得不想想,每天除了必要的上网浏览网页,我们其实还是和桌面图形化软件打交道比较多。那么,我们可以不可以搞个比较好用的框架来让我们更好更快的开发desktop application呢?在JAVA领域,我想大部分程序员已经对SWING之流彻底失去信心了,在.NET下,还好我们有WPF。

那么WPF又是什么呢?WPF全名是Windows Presentation Foundation,不知道是不是因为Bill Gates一心投身公益事业,连微软的产品都要加上Foundation。WPF是微软对WinForm的一个全新的发展。WPF的第一个版本是随.NET 3.0发布的,经历了3.5,到现在4.0已经可以说是进入了成熟期了(可以摘掉Beta的名字了,虽然微软本来就没有加上)。相比较其他图形界面API,WPF最大的优势是界面设计和应用逻辑的分离,至少这是微软官方的说法。WPF是一个相对被很多人忽视的东西,这主要是因为在现在互联网的网页时代,有多少人愿意去搞Desktop Application呢?这个问题我不在这里讨论,因为并没有什么讨论的意义。

当我们开始进行WPF编程以后,我们就会发现WPF看似是一个很好用的东西,表面上看,WPF非常友好,MSDN上的很多Example短小精悍,自己模仿起来是很容易的。但是,真个搞起来的时候,我们就会发现,搞好WPF是很难的(当然,什么东西用好都不容易),特别是当我们要做的界面比较复杂的时候,或者说我们要表现的业务逻辑比较复杂的时候。WPF的程序往往开始搞的时候都是很美好的,随着项目的推进,界面的逻辑越来越复杂,程序的质量会直线下降,一直到完全无法维护的程度。那么,WPF到底能不能搞大型项目呢?是不是像WinForm一样一旦做大了就力不从心了呢?

我想微软给了我们很好的答案,那就是Visual Studio 2010,一个基于WPF的大家伙。我相信,我们自己搞的项目不会有Visual Studio那么大,所以我们对WPF是要有信心的。那么,是什么成就了Visual Studio 2010呢?微软告诉我们,是MVVM,这个MVC的发展。我倒是觉得是MEF这个东西。MEF是什么?MEF全名Managed Extensibility Framework,其实就是微软自己的一个拓展架构,像很多人说的那样,一个微软自己的IoC架构。当MEF碰到WPF,就有了我们这一系列文章的正题,那就是可拓展的界面应用程序。

现在看看上面自己写的东西,感觉自己都不知道自己在说什么,舍不得删啊:)这个可拓展的界面应用程序究竟是个什么东西呢?简单来说,就是一个.NET下的像Eclipse一样的东西。Eclipse强大在哪?它是一个界面应用的Host,任何人都可以在上面开发插件,插件的用途可以是千差万别,但是只要你继承了对应的借口,插件就可以在Eclipse里运行。我们在.NET下,就是需要这样的Host。这样,当我们想开发新的东西的时候,就可以直接切入到业务逻辑上,进行插件的开发,没必要考虑很多环境的问题。同时,还可以对以前开发的插件进行代码重用,或者拓展。当然,我是没有本事搞一个像Eclipse那么复杂的东西的,而且我也没有这样的需要。我们真正需要的就是一个简单的可拓展的程序,我们可以把每天零零散散写的程序都变成这个程序的拓展插件,这样可以慢慢积累自己的代码库。要知道,在现在这个编程语言都在拼库的时代,我们自己写的每一行代码都是十分宝贵的,一定不要让他们在硬盘里发霉,要时常拿出来看看。

下面,作为热身,我们做一个简单的关于MEF的小程序。我们先建立一个Console Project,然后添加MEF的Library: System.ComponentModel.Composition.dll.

然后,我们定义一个简单的接口:

    public interface Plugin
    {
        String PluginName { get; set; }
    }
然后,我们写一下两个接口的实现:

    public class Plugin1 : Plugin
    {
        public String PluginName { get; set; }

        public Plugin1()
        {
            this.PluginName = "Plugin 1";
        }
    }

    public class Plugin2 : Plugin
    {
        public String PluginName { get; set; }

        public Plugin2()
        {
            this.PluginName = "Plugin 2";
        }
    }

下面,我们添加MEF定义。首先我们要加入Using System.ComponentModel.Composition;,当然,如果你有用Resharper的话,请忽略这步,然后:

    [Export(typeof(Plugin))]
    public class Plugin1 : Plugin

    [Export(typeof(Plugin))]
    public class Plugin2 : Plugin
在每个Plugin类上添加Attribute。这样就够了,真的够了哦。最后我们需要一个Host程序来初始化MEF:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

namespace MEFConsoleExample
{
    class Program
    {
        [ImportMany(typeof(Plugin))]
        public Plugin[] Plugins;


        public Program()
        {
            var result = this.Compose();
            if (result == false)
            {
                return;
            }
            else
            {
                foreach (var plugin in Plugins)
                {
                    Console.WriteLine("Plugin name: " + plugin.PluginName);
                }
            }
        }

        static void Main(string[] args)
        {
            var test = new Program();
        }

        private bool Compose()
        {
            var catalog = new AggregateCatalog();
            catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));

            var provider = new ComposablePartExportProvider();

            var container = new CompositionContainer(catalog, provider);
            provider.SourceProvider = container;
            var batch = new CompositionBatch();
            batch.AddPart(this);

            try
            {
                container.Compose(batch);
            }
            catch (CompositionException exception)
            {
                Console.WriteLine(exception.ToString());
                return false;
            }
            return true;
        }
    }
}
就这么简单,运行程序我们会看到:

Plugin name: Plugin 1
Plugin name: Plugin 2
Press any key to continue . . .

当然,上面的这些只是皮毛中的皮毛,不过今天不想写了,以后再慢慢写吧。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值