使用MEF传递参数/属性

时间:2012-03-15 10:28:10

标签: c# module mef modularity

考虑以下样本:
我有一个Car类和一个ILogger接口。我希望ILogger实现记录(控制台,文件,数据库等)汽车规格列表。当然,我想将MEF用于ILogger。但是对于日志记录,我的记录器类应该可以访问汽车的规范。而且我不确定将对象传递给我的记录器类的最佳方法是什么。为了更清楚,这里有一些代码:

class Program
{
    public class Car
    {
        public string Brand { get; set; }
        public string Model { get; set; }
    }

    private CompositionContainer _container;

    [Import(typeof(ILogger))]
    public ILogger logger;

    private Program()
    {
        var catalog = new AggregateCatalog();
        catalog.Catalogs.Add(new AssemblyCatalog(typeof(Program).Assembly));
        this._container = new CompositionContainer(catalog);
        this._container.ComposeParts(this);
    }  

ILogger接口应该有一个Car对象用于记录。而且我不确定我是应该在logger的构造函数中传递它还是作为Property传递它,或者只是一个方法参数。

  • 使用属性:如果我使用属性传递汽车,ILogger界面如下所示:
    public interface ILogger
    {
        Car Car { get; set; }
        void Log();
    }
    

    我可以迭代我的列表项目如下:
    static void Main(string[] args)
    {
        Program p = new Program(); // Composition is performed in the constructor
        var cars = new List()
            {
                new Car() { Brand = "Nissan", Model = "SkyLine" },
                new Car() { Brand = "Porche", Model = "Carrera"},
                new Car() { Brand = "Ferrari", Model = "Enzo"}
            };
        foreach (var car in cars)
        {
            p.logger.Car = car;
            p.logger.Log();
        }
        Console.ReadKey();
    }
    
  • 使用参数:界面:

    public interface ILogger
    {
        void Log(Car car);
    }
    

    和程序:

    foreach (var car in cars)
    {
        p.logger.Log(car);
    }
    
  • 使用构造函数:这就是我似乎迷失的地方。我可以将ILogger界面更改为:

    public interface ILogger
    {
        Car Car {get; set;}
        void Log();
    }
    

    在实施的课程中:

    [Export(typeof(ICarLogger))]
    public class ConsoleLogger : ICarLogger
    {
        public Car Car { get; set; }
        [ImportingConstructor]
        public ConsoleLogger(Car car)
        { 
            this.Car = car;
        }
        public void Log()
        {
            Console.WriteLine("Brand: {0}\tModel: {1}", Car.Brand, Car.Model);
        }
    }
    

这会导致每次我想将新值传递给构造函数时创建CompositionContainer(使用ComposeExportedValue方法)。简单地说,如何将各种变量传递给构造函数而不必再次重建整个CompositionContainer

那么,在您看来,这三种方法中的哪一种更好。如何实现所提到的构造函数方法?希望我能清楚地描述我的问题 对这个冗长的问题表示感谢和道歉 附:我正在使用.Net 4附带的MEF版本。

1 个答案:

答案 0 :(得分:0)

你写道,你想要记录汽车清单,所以不应该这样:

public interface ILogger
{
   void Log(IEnumerable<Car> cars);
}