views:

1088

answers:

2

Hi!

How to fill TODO to make this test pass?

class MyClass { }

[Test]
public void Singleton_by_default_test()
{
    var parentContainer = GetUnityContainer();        
    var container = parentContainer.GetChildContainer();

    // TODO: Add magic here (but do NOT explicitly register MyClass in container!)

    Assert.AreSame(container.Resolve<MyClass>(), container.Resolve<MyClass>());
}

Update: There is a way that uses inheritance.

public class SingletonContainer : UnityContainer
{
    public override object Resolve(Type t, string name)
    {
        var obj = base.Resolve(t, name);
        RegisterInstance(t, name, obj, new ContainerControlledLifetimeManager());
        return obj;
    }
}

I am using container.GetChildContainer() to get container instance so this method does not suite me.

A: 

Try using it as singleton. You can use the following conffiguration for your MyClass:*

<type type="MyClass" mapTo="MyClass">
  <lifetime type="singleton" />
</type>
Mischa
You are registering the type explicitly. I don't want to know in advance all types I'm gonna need.
Konstantin Spirin
+2  A: 

I see where you are going with this. Interesting problem.

I think you can do what you are doing with a Unity Behavior Extension. Here's a great article on the design of Unity that describes the job of certain elements of Unity that a lot of people don't know about: http://msdn.microsoft.com/en-us/library/dd140062.aspx

The Unity Container basically uses a "strategy chain" when handling a resolve request. One of the strategies in the chain is the LifetimeStrategy.

The easiest thing to do would be to create a new strategy and insert it in the chain before the LifetimeStrategy so that when your strategy gets a chance to look at the type, it can register a ContainerControlledLifetimeManager for that type in the current container. It will get to the LifetimeStrategy and there will already be a ContainerControlledLifetimeManager registered for that type.

It might look like this:

public class MakeEverythingSingletonStrategy : BuilderStrategy
{
     public override void PreBuildUp(IBuilderContext context)
     {
          Type objectType = BuildKey.GetType(context.BuildKey);
          context.PersistentPolicies.Set<ILifetimePolicy>(
                  new SingletonLifetimePolicy(), 
                  context.BuildKey);

     }
}

You should be able to apply this configuration to the sub container using the Configure<T> method, passing in a configuration class that adds this new extension.

I found a good sample of someone on Stackoverflow implementing a custom BuilderStrategy:

http://stackoverflow.com/questions/1380375/custom-object-factory-extension-for-unity/1388522#1388522

Anderson Imes