tags:

views:

558

answers:

7

Hi,

I'm looking at the new object initializers in C# 3.0 and would like to use them. However, I can't see how to use them with something like Microsoft Unity. I'm probably missing something but if I want to keep strongly typed property names then I'm not sure I can. e.g. I can do this (pseudo code)

Dictionary<string,object> parms = new Dictionary<string,object>();
parms.Add("Id", "100");

IThing thing = Factory.Create<IThing>(parms)();

and then do something in Create via reflection to initialise the parms... but if I want it strongly typed at the Create level, like the new object intitalisers then I don't see how I can.

Is there a better way? Thanks

+1  A: 

AFAIK, it's not possible to do. I would stay away from reflection in this case if I were you, as reflection is really really slow and could become easily a bottleneck in your application. I think using reflection for this is actually abusing reflection.

Do not shoot yourself in the leg because you want to emulate some syntactic sugar. Just set the fields / properties of the instance one by one, the classic way. It will be much faster than reflection.

Remember: No design pattern is silver bullet. Factory methods and object initializers are nice but try to use common sense and only use them when they actually make sense.

DrJokepu
A: 

I'm not that familiar with Unity, but the idea behind IoC/DI is that you do not construct object yourself, so of course you can't use object initializer syntax.

I guess what you could use from C# 3.0 in your example is an anonymous type instead of Dictionary. No idea if Unity can consume that.

Anyway, if you make those calls like Factory.Create() you are probably using IoC in a wrong way.

Yuriy Ostapenko
A: 

Yuriy,

I'm interested in your answer "you are probably using IoC in a wrong way". What I'm doing is basically using Unity to load at runtime my domain layer so I can swap it out for a mock or different implementations as I wish. I've wrapped the injector with a factory to make things a bit easier. Within my domain layer I'd use "new" as normal. With this in mind, can you expand on why you think I may be making a mistake?

Jon - thanks, I take your point. I don't think I will use reflection but it was an idea to help me around a problem with NHibernate doing an Insert and Update statement in my repository layer.

A: 

Consider investing the time in leaning Unity or Castle or any of the other IOC frameworks available for .net. The IOC will let you transfer the complexity of object initialization from your code to a configuration file. In your application you will use interfaces to access the objects initialize in by the IOC container. The other service the IOC gives you is control of the lifetime of the objects (singletons, etc).

The Landlord
A: 

Graham, the idea behind IoC/DI is that your components declare their dependencies as either constructor parameters or public properties of specific types (usually interfaces). The container then builds a dependency graph and satisfies those (with regards to component lifestyle if case of mature IoC's like Castle Windsor).

So basically you write your components, state dependencies and then register contracts and implementations in IoC container and don't care about constructing objects anymore. You just make a single call similar to Application.Start() :)

The bad thing is that some frameworks are hard to integrate with. Like ASP.NET WebForms, where you don't have control over IHttpHandler creation and cannot setup factories that would use IoC to instantiate those. You can check Ayende's "Rhino Igloo" which does it's best to use IoC in an environment like this.

Yuriy Ostapenko
A: 

Maybe this can help... Have you checked out this blog post?

http://www.cookcomputing.com/blog/archives/000578.html

The author presents a method for building an object from a factory and registering the object in the IoC container.

A: 

This is answered better in this question: http://stackoverflow.com/questions/675545/is-it-possible-to-use-a-c-object-initializer-with-a-factory-method.

There were four possibilities:

  • Accept a lambda as an argument
  • Return a builder instead
  • Use a default constructor, passing in an initialized object
  • Use an anonymous object
Nathan