1

I'm unsure of how to fix my current situation. I'm attempting to create a task:

public class whatever
{
    [Dependency]
    public IReportingBL ReportingBL { get; set; }

    private whatever()
    {
    ...task factory creation, etc.
    }

    private readonly static Lazy<whatever> _instance = new Lazy<whatever>(() => new whatever());

    public static whatever Instance { get { return _instance.Value; }

    public Task GetStuff()
    {
        return _taskFactory.StartNew(() =>
        {
            return ReportingBL.Method1;
        });
    }
}

ReportingBL doesn't get resolved. If I create a new instance of ReportingBL inside the thread then the layers below it don't get resolved.

How do I go about getting unity to work in this situation?

3
  • How exactly are you creating the whatever class? Can you show the code for that? Commented Mar 17, 2015 at 17:51
  • You'll need to synchronize access to the variable if you're accessing it from multiple threads. Commented Mar 17, 2015 at 18:30
  • @Servy I don't need ReportingBL anywhere else but in the thread. If I declare a new ReportingBL inside the thread then it's children don't resolve either. Commented Mar 17, 2015 at 18:42

1 Answer 1

2

You are applying the Singleton Design Pattern. This is a pattern that is frown upon and considered an anti-pattern by some. In Dependency Injection terminology the Singleton pattern can be considered an Ambient Context, which is a pattern that should hardly ever be used in the context of Dependency Injection.

The Singleton Design Pattern does not work well with Dependency Injection, because:

  • With Dependency Injection it is the application's Composition Root who is in control of creating instances and caching them; not the instance itself.
  • Having consumers depend on the public Instance field, causes the consumers to violate the Dependency Inversion Principle and disallows the instance from being replaced, mocked, decorated or intercepted. This hinders maintainability and testability of your application.

Further more, in your code I don't see any calls to the Unity DI framework. Please remember that a DI container is not a magical tool that will allow classes to be initialized 'by them selves'. In your code you new up whatever directly; Unity is not involved in this. Unity (or any DI library for that matter) can only auto-wire the object if it is in control of it. In other words, you will have to call container.Resolve<whatever>() for Unity to build up your instance.

Although you could call container.Resoolve from within the Lazy<T> factory delegate, this forces the class to take a dependency on the container itself, which is commonly referred to as the Service Locator anti-pattern.

Instead, I propose the following changes to your design:

  1. Use constructor injection instead of property injection. Property injection leads to Temporal Coupling.
  2. Make the Composition Root and the container responsible for wiring up object graphs.
  3. Stay away from the Singleton design pattern; use the container's Singleton Lifestyle instead.

This results in the following code:

public interface IWhatever
{
    Task GetStuff();
}

public class Whatever : IWhatever
{
    private readonly IReportingBL reportingBL;

    public whatever(IReportingBL reportingBL) {
        this.reportingBL = reportingBL;
    }

    public Task GetStuff() {
        return _taskFactory.StartNew(() => {
            return ReportingBL.Method1;
        });
    }
}

// Some consumer of whatever
public class MyController : Controller
{
    private readonly IWhatever whatever;

    public MyController(IWhatever whatever) {
        this.whatever = whatever;
    }

    public ActionResult Index() {
        return View(this.whatever.GetStuff());
    }
}

In your composition root, you can configure the class as follows:

var container = new UnityContainer();

container.RegisterType<IReportingBL, ReportingBL>(
    new ContainerControlledLifetimeManager());
container.RegisterType<IWhatever, Whatever>(
    new ContainerControlledLifetimeManager());

var controller = container.Resolve<MyController>();

controller.Index();
Sign up to request clarification or add additional context in comments.

4 Comments

This won't work if I need to manage all of the threads it makes though does it?
@Shawn: I'm not sure what you mean. Do note though that in general your application code should not have to deal with threading and parallelism and you should prevent moving dependencies from thread to thread from within your application. This is infrastructural logic that should be separated from application code and placed inside the Composition Root of the application.
the purpose of the whatever class is to manage the threads created by GetStuff. It looks like with your answer I'll be creating a new instance of whatever in every class I need to call it.
I declared an interface for my singleton and used unitys singleton control. I was confused because all of my config is in the web.config. Thanks for your help.

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.