Consider the following sample:
I have a Car
class and an ILogger
interface. I'd like the ILogger
implementations to log (console, file, db, etc) a list of cars' specs. And of course, I want to use MEF for ILogger. But for logging, my logger class should have access to a car's specification. And I'm not sure what would be the best way to pass objects to my logger classes. To be more clear, here's some code:
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);
}
The ILogger
interface should get a Car
object for logging. And I'm not sure whether I should pass it in logger's constructor or as a Property, or just a method parameter.
- 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(); }
Using parameter: The interface:
public interface ILogger { void Log(Car car); }
and the program:
foreach (var car in cars) { p.logger.Log(car); }
Using constructor: This is where I seem to be lost. I can change the
ILogger
interface to :public interface ILogger { Car Car {get; set;} void Log(); }
And in the implemented class:
[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); } }
But this leads to creating the CompositionContainer
everytime I want to pass a new value to the constructor (By using ComposeExportedValue
method). Put it simply, How can I pass various variables to the constructor without having to rebuild the whole CompositionContainer
again?
So, which of these 3 approaches are better in your opinion. And how can I implement the constructor approach as mentioned? Hope I described my problem clearly.
Thanks and apologies for the lengthy question.
P.S. I'm using the MEF version which comes with .Net 4.