How to implement additional RegisterInstance behavior

May 4, 2009 at 8:12 AM
Edited May 4, 2009 at 8:18 AM

I already created work item for this but I don't have high hopes that it would happen any time soon :), so here I am asking if anyone knows if it is possible and (if it is) how to implement RegisterInstance method NOT to use any life time policy so resolve calls would result with a fresh copy of an instance being retrieved as it was in the moment of registration?

In other words, how to make this unit test passing?







namespace TestProject1 
        using Microsoft.Practices.Unity

public class UnitTest1 
            public void TestMethod1() 
                var person = new Person { Name = "Nikola" }; 
                IUnityContainer container = new UnityContainer(); 
person1 = container.Resolve<Person>(); 
                person1.Name = "John"; 

var person2 = container.Resolve<Person>(); 
.AreEqual(person2.Name, "Nikola"); 

class Person 
            public string Name { get; set; } 

May 4, 2009 at 8:58 AM
How would you implement this feature? Short of serializing the original instance and storing the blob away to reconstitute it, I'm not sure this is even possible.

I'm also not sure what this does that just registering a type with the appropriate constructor / property values doesn't.

May 4, 2009 at 9:46 AM
The scenario I have is that the instance setup is kinda complex (includes DB reads etc) so I'm not sure if providing parameters to be used with constructor + type registration would be helpfull there

I am also not sure how this should be implemented (if possible at all) but here are couple of (I'm sure very naive) ideas:
1. binary serialization\deserialization trick as a way of of getting deep copy (would fail if not everything marked as serializable - which is OK IMHO)
2. Relying on convention that class would implement ICloneable (if class implements it call it while registering, if not resolve it as singleton)
3. Framework enhancement:
Adding RegisterInstance method overload accepting Func<T,T> which would be the method to be called BEFORE resolving in which case implementation of deep copy functionality would fully be on type author.
(Might be interesting for other things to complement interceptors post resolution processing with pre resolution processing capabilities)

Does this make any sense? :)

May 4, 2009 at 11:10 PM
My first thought is that you have expensive initialisation costs and therefore don't want to create a new object. 

If this is correct, consider removing this information to a separate object, maybe with a singleton lifetime and use the Dependency attribute to inject this information to a property or in the constructor.

If that is not practical, then consider other patterns like lazy load.

One of our recent projects had a similar issue with initialisation but we removed the expensive parts by using Unity to resolve a mock datacontext and therefore effectively removed the DB from unit testing completely.  A subsequent custom msbuild task verified the DBML with the DB rebuilt from scripts per build cycle and failed the build if they didn't match.

So as a general rule, if I have expensive initialisation, wrap in it using DI so you can removing it when you don't need it.