Dependency Injection in .NET

Author: Mark Seemann
4.4
All Stack Overflow 36
This Year Stack Overflow 9
This Month Stack Overflow 1

About This Book

Dependency Injection in .NET introduces DI and provides a practical guide for applying it in .NET applications. The book presents the core patterns in plain C#, so you'll fully understand how DI works. Then you'll learn to integrate DI with standard Microsoft technologies like ASP.NET MVC, and to use DI frameworks like StructureMap, Castle Windsor, and Unity. By the end of the book, you'll be comfortable applying this powerful technique in your everyday .NET development.

This book is written for C# developers. No previous experience with DI or DI frameworks is required.

Purchase of the print book comes with an offer of a free PDF, ePub, and Kindle eBook from Manning. Also available is all code from the book.

Winner of 2013 Jolt Awards: The Best Books--one of five notable books every serious programmer should read.

Summary

Dependency Injection in .NET, winner of the 2013 Jolt Awards for Productivity, presents core DI patterns in plain C#, so you'll fully understand how DI works, covers integration with standard Microsoft technologies like ASP.NET MVC, and teaches you to use DI frameworks like Structure Map, Castle Windsor, and Unity.

About the Technology

Dependency Injection is a great way to reduce tight coupling between software components. Instead of hard-coding dependencies, such as specifying a database driver, you inject a list of services that a component may need. The services are then connected by a third party. This technique enables you to better manage future changes and other complexity in your software.

What's Inside

  • Many C#-based examples
  • A catalog of DI patterns and anti-patterns
  • Using both Microsoft and open source DI frameworks

Comments

by anonymous   2018-03-19

Why have you created the instance of the object if I will not use it at all.

Mark Seemann said in his book Dependency Injection in .NET, "creating an object instance is something the .Net Framework does extremely fast. any performance bottleneck your application may have will appear in other place, so don't worry about it."

Please note that Dbcontext enables lazy loading by default. Just by instantiating it, it doesn't have much impact on the performance. So, I would not worry about Dbcontext.

However, if you have some custom classes doing heavy lifting inside constructor, then you might want to consider refactoring those.

If you really want to compare the performance, you could wrap those dependencies with Lazy, and see how much performance you gain. Does .net core dependency injection support Lazy.

by anonymous   2017-08-20

About testability

Due to the use of singletons and static classes MyViewModel isn't testable. Unit testing is about isolation. If you want to unit test some class (for example, MyViewModel) you need to be able to substitute its dependencies by test double (usually stub or mock). This ability comes only when you provide seams in your code. One of the best techniques used to provide seams is Dependency Injection. The best resource for learning DI is this book from Mark Seemann (Dependency Injection in .NET).

You can't easily substitute calls of static members. So if you use many static members then your design isn't perfect.

Of course, you can use unconstrained isolation framework such as Typemock Isolator, JustMock or Microsoft Fakes to fake static method calls but it costs money and it doesn't push you to better design. These frameworks are great for creating test harness for legacy code.

About design

  1. Constructor of MyViewModel is doing too much. Constructors should be simple.
  2. If the dependecy is null then constructor must throw ArgumentNullException but not silently log the error. Throwing an exception is a clear indication that your object isn't usable.

About testing framework

You can use any unit testing framework you like. Even MSTest, but personally I don't recommend it. NUnit and xUnit.net are MUCH better.

Further reading

  1. Mark Seeman - Dependency Injection in .NET
  2. Roy Osherove - The Art of Unit Testing (2nd Edition)
  3. Michael Feathers - Working Effectively with Legacy Code
  4. Gerard Meszaros - xUnit Test Patterns

Sample (using MvvmLight, NUnit and NSubstitute)

public class ViewModel : ViewModelBase
{
    public ViewModel(IMessenger messenger)
    {
        if (messenger == null)
            throw new ArgumentNullException("messenger");

        MessengerInstance = messenger;
    }

    public void SendMessage()
    {
        MessengerInstance.Send(Messages.SomeMessage);
    }
}

public static class Messages
{
    public static readonly string SomeMessage = "SomeMessage";
}

public class ViewModelTests
{
    private static ViewModel CreateViewModel(IMessenger messenger = null)
    {
        return new ViewModel(messenger ?? Substitute.For<IMessenger>());
    }

    [Test]
    public void Constructor_WithNullMessenger_ExpectedThrowsArgumentNullException()
    {
        var exception = Assert.Throws<ArgumentNullException>(() => new ViewModel(null));
        Assert.AreEqual("messenger", exception.ParamName);
    }

    [Test]
    public void SendMessage_ExpectedSendSomeMessageThroughMessenger()
    {
        // Arrange
        var messengerMock = Substitute.For<IMessenger>();
        var viewModel = CreateViewModel(messengerMock);

        // Act
        viewModel.SendMessage();

        // Assert
        messengerMock.Received().Send(Messages.SomeMessage);
    }
}
by anonymous   2017-08-20

Edit, the dependency always "exists" but it was moved outside of the class notice that IMyServices can now be defined in the same project as HomeController when MyService is in totally another class. and your DLL with HomeController can compile without knowing about your MyService dll effectivly decoupling them.


this is a very complex topic and you should read a book about it. reading blogs videos and so on didn;t really help.

this is a good book. http://www.amazon.com/Dependency-Injection-NET-Mark-Seemann/dp/1935182501

this is a great vidoe lecture series first 5 videos are about DI in general http://channel9.msdn.com/Blogs/mtaulty/Prism--Silverlight-Part-1-Taking-Sketched-Code-Towards-Unity

initilization is focused in a COMPOSITION ROOT http://blog.ploeh.dk/2011/07/28/CompositionRoot/

and the pattern you shown here is CONSTRUCTOR INJECTION

https://softwareengineering.stackexchange.com/questions/177649/what-is-constructor-injection

by anonymous   2017-08-20

In addition to what Paul T Davies and Magnus Backeus have said. I think that at the end of the day it would be a people and cultural issue. If people are open minded and willing to learn it will be relatively easy to convince them. If they consider you a 'junior' (which is a bad sign because the only thing that matters is what you say not how old/experienced you are) you can appeal to a 'higher authority':

Stored procedures are dead and you are not the only one who thinks so:

It is startling to us that we continue to find new systems in 2011 that implement significant business logic in stored procedures. Programming languages commonly used to implement stored procedures lack expressiveness, are difficult to test, and discourage clean modular design. You should only consider stored procedures executing within the database engine in exceptional circumstances, where there is a proven performance issue.

There is no point in convincing people that are not willing to improve and learn. Even if you manage to win one argument and squeeze in NHibernate, for example, they may end up writing the same tightly coupled, untestable, data-or-linq-oriented code as they did before. DDD is hard and it will require changing a lot of assumptions, hurt egos etc. Depending on the size of the company it may be a constant battle that is not worth starting.

Driving Technical Change is the book that might help you to deal with these issues. It includes several behavior stereotypes that you may encounter:

  • The Uninformed
  • The Herd
  • The Cynic
  • The Burned
  • The Time Crunched
  • The Boss
  • The Irrational

Good luck!

by anonymous   2017-08-20

Without modifing class A code you won't be able to UT the ReadBlock method using moq. You'll be able to UT this method using code weaving tools(MsFakes, Typemock Isolator and etc...)

For example(MsFackes):

[TestMethod]
public void TestMethod1()
{
    using (ShimsContext.Create())
    {
        ShimCloudBlockBlob.AllInstances.<the method you want to override>  = (<the method arguments>) => {};
    }
}

In side the using scope you'll be able to override any method CloudBlockBlob has, through the property AllInstances.

In the next section I'm going to discuss all the other options you have...

Option 1:

    public class A
    {
        private IBlockBlob _blockBlob;

        public A(IBlockBlob blockBlob)
        {
            _blockBlob = blockBlob;
        }

        public void ReadBlock()
        {
            _blockBlob.DoSomething();
        }
    }

Since you create a new instance each time call ReadBlock(your method current behavior...), you better inject a factory instead of wrapper and DoSomething should be create; Option 2:

    public class A
    {
        private readonly IFactoryBlockBlob _blobFctory;

        public A(IFactoryBlockBlob blobFctory)
        {
            _blobFctory = blobFctory;
        }

        public void ReadBlock()
        {
           var blob =  _blobFctory.Create();
        }
    }

However based on your question and your comments it seems that your class 'has a dependency' instead of 'need a dependency'.

enter image description here

(Mark Siemens wrote a great book about DI, this chart was taken from his book)

With this new piece of inforamtion you method should be something like; Option 3:

    public class A
    {
        public void ReadBlock(ICloudBlob blob)
        {
        }
    }

But you don't want to change the signeture of the method:

    public class A
    {

        public void ReadBlock()
        {
            ReadBlock(new CloudBlockBlob(<the params bla bla...>));
        }

        internal void ReadBlock(ICloudBlob blob)
        {
        }
    }

Add InternalsVisibleToAttribute, then verify the behavior of the internal method.

By reading between the lines, it feels to me that your class is a kind of "legacy code", by saying "legacy code" I mean class that do the job, won't change and verifying his behavior might be a waste of time. In the past I've posted a chart(in this answer) which may help you to decide the way to handle this case.

by anonymous   2017-08-20

Mocking means that you develop your software components (classes) in a way that any class with behaviour is used/consumed/called-upon as an interface (or abstract class). You program to an abstraction. Run-time you use something (service locator, DI container, factory, ...) to retrieve/create those instances.

The most common way is to use construction injection. Here is an excellent explanation of why one would use DI, and examples of how to do it.

In your case, your component that uses the Entity Framework (your repository for instance) must implement a repository-interface, and any class that uses your repository should use it as an interface.

This way, you can mock the repository in your unittests. Which means that you create a unit-test-repository class (which has nothing to do with any database or EF), and use that when you create the instance of the class that you want to unit-test.

Hopefully this helps. There are many source to be found. Personally I just read this book and I found it to be very good. This is the authors blog.

by anonymous   2017-08-20

Funny you should ask to have it explained like you were six years old; here's an explanation like you were five years old :)

everywhere I look I see a push in the direction of containers such as Castle Windsor

Frankly, I think the reason for that is that most people actually don't understand what Dependency Injection is, which means that instead of grasping the concept of Inversion of Control, they go looking for a replacement for the new keyword they're already used to. Then they find a DI Container and (mis)use it as a Service Locator. Unfortunately, that's very easy to do.

This is the reason why, in my book, I explain all the DI concepts without coupling the explanation to any single DI Container. That's actually the majority of the book.

Service Locator and Dependency Injection are two fundamentally different attempts at achieving loose coupling. Service Locator has many disadvantages, and offers no advantages not also offered by DI. This is why I think it's safe to call Service Locator an anti-pattern.

You don't need a DI Container to use DI; in fact, I would say that unless you take a rather sophisticated approach, it's probably better to avoid one.

by anonymous   2017-08-20

On the last part of the article (The UI), the startup file is accessing the repo. Is this logical? If so why?

I believe you are referring the following code -

services.AddDbContext<ApplicationContext>(options => 
  options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
services.AddTransient<IUserService, UserService>();
services.AddTransient<IUserProfileService, UserProfileService>();

It is normal for UI Project to reference other projects, and register dependencies in IoC container, because Composition Root should be placed as close to the application's entry point as possible.

var userService = new UserService();

If you instantiate UserService using new keyword in UI, they become tightly coupled - a change in one class forces a change in another.

IoC container solves the dependencies issue by resolving dependencies at runtime and pass them as needed.

If you want to know more about DI, you might want to read Dependency Injection in .NET by Mark Seemann and Adaptive Code via C# by Gary McLean Hall

by anonymous   2017-08-20

I have struggled with the same question for quite some time. I habe make the experience that you usually do not need a ServiceLocator (btw: best description of this anti pattern here and what you can do to avoid it in the corresponding, very awsome, book).

Please the refactoring of your code below. The basic idea here is that you have just one root object that acts as the composition root (Program) and all child dependencies of the complex object graph below that root are automatically resolved by the container.

public class Bootstrapper
{
    private readonly UnityContainer _container;

    private Bootstrapper()
    {
        _container = new UnityContainer();
    }

    public Program Intialize()
    {
        this.ConfigureDependencies(UnityContainer container);
        return this.GetCompositionRoot();
    }

    private void ConfigureDependencies()
    {
        _container.RegisterType<IUserProvider, UserProviderSimple>();
        _container.RegisterType<IUserService, UserServiceSimple>();
        _container.RegisterType<Program, Program>();
    }

    private Program GetCompositionRoot()
    {
        return _container.Resolve<Program>();
    }
}

public class Program
{
    public Program(IUserService userService)
    {
        _userService = userService ?? throw AgrumentNullExcpetion(nameof(userService));
    }

    static void Main(string[] args)
    {
        var program = new Bootstrapper().Initialize();
        program.Run();
    }

    public void Run()
    {
        // Do your work using the injected dependency _userService
        // and return (exit) when done.
    }
}
by anonymous   2017-08-20

Seem like Lookup class itself is a Service Locator Pattern.

IRepository<Table001> table001Repository = container.Resolve<IRepository<Table001>>();

Service Locator has few problems. One of them is it doesn't follow Don't call us, we'll call you principle. It directly ask for the things we need rather than handed them to us.

With the service locator, we have to examine the code, searching for capricious calls that retrieve a required service. Constructor injection allowed us to view dependencies—all of them—with a glance at the constructor, or at a distance, via IntelliSense.

Solution

Ideally, you want to inject IRepository<Table001> to MyClass. I also use the similar approach in my projects.

public class MyClass
{
    private readonly IRepository<Table001> _table001;

    public MyClass(IRepository<Table001> table001)
    {
       _table001 = table001;
    }
}

If you see yourself injecting a lot of dependencies into a single class, it might be that the class violates Single Responsibility Principle. You might want to separate it to different classes.

"creating an object instance is something the .NET Framework does extremely fast. Any performance bottleneck your application may have will appear in other places." - Mark Seemann author of Dependency Injection in .Net