Рассмотрим следующий пример:
У меня есть 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
для ведения журнала. И я не уверен, следует ли передавать его в конструкторе логгера или как свойство, или просто как параметр метода.
- Using property: If I use a property for passing a car, the
ILogger
interface looks like this:public interface ILogger { Car Car { get; set; } void Log(); }
And I can iterate through my list items as below:
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.