Decorator

May 2, 2012 at 8:57 AM

Is it possible to use MetroIOC and the decorator pattern?

Sorry for teaching how to suck eggs but some may not know what I mean I.e. I have A: IInterface, B:IInterface where B's constructor is B(IInterface toDecorate). I would like to request an IInterface and get back:-

IInterface = new B(new A());

Also I notice MetroIOC throws exceptions a lot as part of normal control flow - is there a reason for this?

 

Thanks for creating this! it's very useful!

Coordinator
Jun 16, 2012 at 11:17 PM

HI,

 

Short answer is: Sorry, no - there's nothing out the box to support this.

Slightly longer answer: Internally, I create a func<object> to spin up an instance when calling Resolve, and I'm probably going to expose this through the Register API (which means the whole, messy, Configuration API becomes redundant and I can ditch it). At that point, you may well be able to do something like:

container.Register(() => new B(new A()));

although this could get messy if you add constructor parameters to A and/or B...

I'll have a read round and see how other containers achieve this.

 

re: Exceptions - it's just a personal opinion thing - I think if your container is going to stop the code from executing properly, then as a dev you want it to fail hard and fast before you ship it off to production. Personally, I'd rather get an exception and fix the bug whilst creating the app than do something softer (like return null or whatever) and maybe miss (and ship) the bug...

 

If you don't want Resolve to throw, then you can use TryResolve which will swallow the exception for you and return null if it fails.

 

 

cheers, Ian

Aug 3, 2012 at 9:03 AM

Thanks Ian for your reply, sorry it took so long to reply - I didn't get notified.

RE exceptions - I agree fail fast, fail hard, but internally you are using exceptions as program flow, this seriously degrades debug performance. It takes almost a minute to load my app in debug mode and the output windows must have almost 100 lines of this:

A first chance exception of type 'MetroIoc.ResolutionException' occurred in MetroIoc.DLL'Relay.Methods.FileBased.exe' (Managed (v4.0.30319))

I'm guessing that if the constructor isn't a default constructor you throw the exception, swallow it and try something else. 

Aug 3, 2012 at 9:12 AM

Actually I'm running an old version, but this is easily resolved by changing

parameter = ResolveInstance(null, key, lifetimeScope);

Inside MetroContainer.Resolve.cs to

parameter = GetTypeFromContainer(key) == null ? Resolve(parameterInfo.ParameterType) : Resolve(null, key);

This runs loads quicker in debug mode now.

Ta

Ross

Coordinator
Aug 6, 2012 at 1:42 AM

Thanks Ross, yes I've definitely done the whole "who wrote this shit? oh it was me 12 months ago" thing here... am contemplating tidying it up. Feel free to open a PR for your change if it improves perf and as long as all the tests are still green, then I'll happily pull it in :-)

 

 

(Yes, my original delay in answering was because I didn't get a notification. ho hum)

 

cheers, Ian