Рассмотрим следующий образец:
У меня есть класс 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.
Вы хотите создавать новый ILogger для каждого автомобиля ? Или, как предлагает @blindmeis, IEnumerable внутри ILogger? У меня была аналогичная проблема, см. Мой ответ на: http://stackoverflow.com/q/9626227/210709 –
IAbstract
@IAbstract: см. Мой комментарий к ответу blindmeis. – Kamyar