2

We have 3 diffrent classes that are linked. We register this in unity.

We have problems resolving them correctly.

The classes look like this:

public class A: IA
{
    public IB B { get; private set; }
    public IC C { get; private set; }

    public A(IB b, IC c)
    {
        this.B = b;
        this.C = c;
    }
}

public class B : IB
{
    public IC C { get; private set; }

    public B(IC c)
    {
        this.C = c;
    }
}

public class C :IC{}


public interface IA
{
    IB B { get; }
    IC C { get; }
}
public interface IB{
    IC C { get; }
}
public interface IC{}

The unity config looks like this:

<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
   <container>
        <register type="IA" mapTo="A" />
        <register type="IB" mapTo="B" />
        <register type="IC" mapTo="C" />
      </container>
</unity>

This is our Main class where we are trying to Resolve A from unity and get the same C object in both the A object and the B object.

public class Main
{
    public Main()
    {
        //This works..
        IC objC = new C();
        IB objB =new B(objC);
        IA objA = new A(objB,objC);

        //We want to do this.
        //How do we register in Unity to ensure we get the same object for C in both A and B
        IA obj1 = Unity.Resolve<IA>();
        Debug.Assert(obj1.C == obj1.B.C);


        //It's very important that two diffrent resolved objects of A don't have the same C object
        IA obj2 = Unity.Resolve<IA>();
        Debug.Assert(obj2.C == obj2.B.C);
        Debug.Assert(obj1.C != obj2.C);
    }
}

Is this possible to achive in unity? Maybe by using some Lifetime Manages?

2 Answers 2

1

You can use a Per Resolve lifetime manager for C. This tells Unity to create a new instance of C for every separate Resolve call. However during a single resolve only one instance of C will be used to inject into the object graph.

The configuration would look like this:

<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
  <container>
    <register type="IA" mapTo="A" />
    <register type="IB" mapTo="B" />
    <register type="IC" mapTo="C">
      <lifetime type="perresolve"/>
    </register>
  </container>
</unity>

With the above config then the Asserts will pass.

Sign up to request clarification or add additional context in comments.

Comments

1

By specifying IC in the constructor of A you are communication that you want a different instance of C while actually want to refer to the same C as used in B

You could solve your problem in Unity with lifetime management.

But if it's really important to have the same instance USE the same instance from your code. By doing so you communicate your intent more clearly and the importance of it is visible to maintainers after you.

class A{
   ...
   IC C { get{ return B.C; }}

   public A (IB b){...}
   ...
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.