c# - How to achieve object scoped singletons in the Unity Container? -
assume have following class structure:
public class outer { [dependency] public func<inner> innerfactory { get; set; } } public class inner { }
in autofac can done in following way (and describes behaviour looking for; ignore fact stupid contrived example):
[testmethod] public void autofacmakesthiseasy() { var builder = new containerbuilder(); builder.registertype<outer>().propertiesautowired(); builder.registertype<inner>().instanceperowned<outer>(); var container = builder.build(); var outer1 = container.resolve<owned<outer>>().value; var inner1 = outer1.innerfactory(); var inner2 = outer1.innerfactory(); var outer2 = container.resolve<owned<outer>>().value; var inner3 = outer2.innerfactory(); var inner4 = outer2.innerfactory(); assert.arenotsame(outer1, outer2, "outer1 == outer2"); assert.aresame(inner1, inner2, "inner1 != inner2"); assert.arenotsame(inner2, inner3, "inner2 == inner3"); assert.aresame(inner3, inner4, "inner3 != inner4"); }
how can achieve same behaviour in unity following test passes?
[testmethod] public void unityhasmescratchingmyhead() { var container = new unitycontainer(); //// shoud here? var outer1 = container.resolve<outer>(); var inner1 = outer1.innerfactory(); var inner2 = outer1.innerfactory(); var outer2 = container.resolve<outer>(); var inner3 = outer2.innerfactory(); var inner4 = outer2.innerfactory(); assert.arenotsame(outer1, outer2, "outer1 == outer2"); assert.aresame(inner1, inner2, "inner1 != inner2"); assert.arenotsame(inner2, inner3, "inner2 == inner3"); assert.aresame(inner3, inner4, "inner3 != inner4"); }
note: dearly love ditch unity decent ioc, going hard sell.
if innerfactory
inner
instead of func<inner>
solution perresolvelifetimemanager
[testmethod] public void unityhasmescratchingmyhead() { var container = new unitycontainer(); container.registertype<inner>(new perresolvelifetimemanager()); var outer1 = container.resolve<outer>(); //... , on.
however because have factory need make little more complicated. need make factory perresolve have objects factory makes same instance (containercontrolledlifetimemanager
). via following:
[testmethod] public void unityhasmescratchingmyhead() { var container = new unitycontainer(); container.registertype<func<inner>>(new perresolvelifetimemanager(), new injectionfactory(x => { var child = x.createchildcontainer(); child.registertype<inner>(new containercontrolledlifetimemanager()); return new func<inner>(() => child.resolve<inner>()); })); var outer1 = container.resolve<outer>(); var inner1 = outer1.innerfactory(); var inner2 = outer1.innerfactory(); var outer2 = container.resolve<outer>(); var inner3 = outer2.innerfactory(); var inner4 = outer2.innerfactory(); assert.arenotsame(outer1, outer2, "outer1 == outer2"); assert.aresame(inner1, inner2, "inner1 != inner2"); assert.arenotsame(inner2, inner3, "inner2 == inner3"); assert.aresame(inner3, inner4, "inner3 != inner4"); }
one thing of note, unity extensible. if going doing little work make instanceperownedlifetimemanager<t>
, use , not need worry generating factories @ all.
Comments
Post a Comment