2012-03-15 3 views
0

Рассмотрим следующий образец:
У меня есть класс Car и интерфейс ILogger. Я бы хотел, чтобы версии ILogger регистрировали (консоль, файл, db и т. Д.) Список спецификаций автомобилей. И, конечно, я хочу использовать MEF для ILogger. Но для ведения журнала мой класс журнала должен иметь доступ к спецификации автомобиля. И я не уверен, что было бы лучшим способом передать объекты в мои классы logger. Чтобы быть более ясным, вот некоторый код:Передача параметров/свойств с помощью MEF

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 объект для регистрации. И я не уверен, следует ли передавать его в конструкторе журнала или в качестве свойства или просто в качестве параметра метода.

  • Используя свойство: Если я использую свойство для передачи автомобиля, интерфейс 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?

Итак, какой из этих трех подходов лучше, на ваш взгляд. И как я могу реализовать конструктор , как упомянуто? Надеюсь, я четко описал свою проблему.
Спасибо и извиниться за длинный вопрос.
P.S. Я использую версию MEF, которая поставляется с .Net 4.

+0

Вы хотите создавать новый ILogger для каждого автомобиля ? Или, как предлагает @blindmeis, IEnumerable внутри ILogger? У меня была аналогичная проблема, см. Мой ответ на: http://stackoverflow.com/q/9626227/210709 – IAbstract

+0

@IAbstract: см. Мой комментарий к ответу blindmeis. – Kamyar

ответ

0

Вы писали вы хотите войти в список автомобилей, так что не должно это быть:

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

Спасибо за ответ, но образец был просто чем-то объяснить мою проблему с передачей параметров. – Kamyar

Смежные вопросы