inversion of control - How to force a registered "ambient" object to be resolved? -
by "ambient object," mean 1 present doing in background, nobody else knows about. example, object hooks events on variety of other objects , logs messages when fire.
the problem is: since nobody except unity builder knows object exists, nobody resolves it, , never gets created. there elegant solution problem?
i create dummy class so:
public class ambientobject { public object theobject { get; set; } }
create factory methods return ambients inside ambientobject
wrappers each case, register them unity, , have composition root container.resolveall<ambientobject>()
(and ignore return value) ensure they're created, that's not elegant.
it sounds want unity automatically resolve instance in background.
there's lot of ways of doing it, can think of two:
1. when creating container lazy.
public static class ioccontainer { private imyambient _ambient; private static readonly lazy<iunitycontainer> container = new lazy<iunitycontainer>(() => { var container = new unitycontainer(); // registration. container.registertype<imyambient, ambient>(); _ambient = container.resolve<imyambient>(); _ambient.dostuff(); return container; }); public static iunitycontainer instance { { return container.value; } } }
2. register unitycontainerextension.
public static class ioccontainer { private static readonly lazy<iunitycontainer> container = new lazy<iunitycontainer>(() => { var container = new unitycontainer() .addnewextension<ambientcreation>(); container.registertype<imyambient, ambient>(); return container; }); public static iunitycontainer instance { { return container.value; } } } public class ambientcreation: unitycontainerextension { protected override void initialize() { // using precreation, may want one? context.strategies.addnew<ambientcreationstrategy>(unitybuildstage.precreation); } } public class ambientcreationstrategy: builderstrategy { private iunitycontainer getunityfrombuildcontext(ibuildercontext context) { var lifetime = context.policies.get<ilifetimepolicy>(namedtypebuildkey.make<iunitycontainer>()); return lifetime.getvalue() iunitycontainer; } public override void prebuildup(ibuildercontext context) { // runs @ every resolve. can decide when create ambient object. } }
i'm using later create log-objects based on stack. maybe can in right direction? downside both options there's no magic going on @ all. moves logic part of application. , 1 may argue buildstrategies aren't supposed used this.
more info: http://weblogs.asp.net/ricardoperes/unity-part-10-custom-build-strategies
Comments
Post a Comment