More improvements for ResolveImp

Feb 27, 2009 at 12:39 AM
InitializeInstace is alway called after CreateInstance so merge with a little check for Reuse.None.
Change GetEntry to a loop instead of recursive.
code below:


private TService ResolveImpl<TService, TFunc>(string name, Func<TFunc, TService> invoker, bool throwIfMissing)




var key = new ServiceKey(typeof(TService), typeof(TFunc), name);



entry = GetEntry<TService>(key);



if (entry != null)




switch (entry.Reuse)




case ReuseScope.Hierarchy:






case ReuseScope.Container:



if (entry.Container != this)




// If the container for the registration entry is



// not the same as the current container, clone



// the entry and register locally on this container



// for further resolutions.


services[key] = entry = entry.CloneFor(








case ReuseScope.None:









throw new ResolutionException(Properties.Resources.ResolutionException_UnknownScope);





if (entry.Instance == null)




return CreateAndInitializeInstance<TService, TFunc>(entry, invoker);




return (TService)entry.Instance;




// entry is not found



if (throwIfMissing)



return ThrowMissing<TService>(name);






return default(TService);




private static TService CreateAndInitializeInstance<TService, TFunc>(ServiceEntry<TService> entry, Func<TFunc, TService> invoker)




var factory = (TFunc)entry.Factory;



var instance = invoker(factory);



// Save instance if Hierarchy or Container Reuse



if (entry.Reuse != ReuseScope.None)


entry.Instance = instance;


// Track for disposal if necessary



if (entry.Owner == Owner.Container && instance is IDisposable)



new WeakReference(instance));



// Call initializer if necessary



if (entry.Initializer != null)


entry.Initializer(entry.Container, instance);


return instance;




private ServiceEntry<TService> GetEntry<TService>(ServiceKey key)




ServiceEntry entry = null;



// Go up the hierarchy always for registrations.



Container container = this;



while (!, out entry) && container.parentContainer != null)



container = container.parentContainer;



return (ServiceEntry<TService>)entry;



Feb 27, 2009 at 3:36 AM
Would be SO much better if you could submit a patch!!!

It's hard to do the diff from this (badly) formatted crap made by the comment form :S

Trying to capture changes anyway...

Feb 27, 2009 at 3:57 AM
Cool refactorings Dennis!
Will be in for the next refactoring-only screencast.

BTW, the initializer being run with the wrong container needed a new test to showcase the bug, which you fixed in your code ;)