如何MEF初始化方法

时间:2014-02-05 14:38:59

标签: c# .net mef

我是MEF的新手。我想知道何时通过组合初始化实例而不是调用它们的构造函数。例如,我不确定如何在MEF中解决以下问题。如果Manager类在另一个DLL中并在Program

中引用
class Program
{
    static void Main(string[] args)
    {
        var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
        var container = new CompositionContainer(catalog);

        var manager= container.GetExportedValue<Manager>();
        container.ComposeParts(manager);
    var letter =   manager.Letter;
        Console.ReadKey();
    }
}

//Manager Class is Business Access Layer referenced to Program as DLL

[Export]
public class Manager
{
    private Letter _letter;

[Import]
    public Letter Letter
    {
        get { return _letter ?? (_letter = InitializeComposeLetter()); }
    }

    private Letter InitializeComposeLetter()
    {
        var attachments = new List<string>();

        var details             = new StringBuilder();
        var attachmentDirectory = ConfigurationManager.AppSettings["attachmentsDirectory"];
        var letterPath          = ConfigurationManager.AppSettings["letterPath"];

        if (Directory.Exists(attachmentDirectory))
        {
            var files = Directory.EnumerateFiles(attachmentDirectory);
            attachments = files.ToList();
        }

        if (File.Exists(letterPath))
        {
            var lines = File.ReadAllLines(letterPath);
            foreach (var line in lines)
            {
                details.Append(line);
                details.Append(Environment.NewLine);
            }
        }

        //*********************QUESTION IS HERE *************//
        var letter = new Letter() //SHOULD I MEF THIS OUT ??? IF SO HOW??
            {
                Subject = ConfigurationManager.AppSettings["defaultEmailTitle"],
                Details = details.ToString(),
                Attachments =  attachments,
            };

        return letter;

    }
}

1 个答案:

答案 0 :(得分:0)

由于您未使用自动实现的属性,因此应导入字段而不是属性:

[Import]
private Letter _letter;

请注意,如果没有Letter类型的部分,则Manager的组成将失败。如果您想自己处理它(如代码示例所示),您可以使用ImportAttribute.AllowDefault属性:

[Import(AllowDefault = true)]
private Letter _letter;

最后,您不需要拨打ComposeParts。这是您创建的对象所必需的。如果对象是由容器创建的,则组合在幕后完成。

因此,对于您创建的对象:

var manager = new Manager();
container.ComposeParts(manager);

否则:

var manager= container.GetExportedValue<Manager>();

注意如果合成失败,GetExportedValue会抛出。还有其他GetExportXXX方法不会抛出。根据您的需要选择一个。