Configure StructureMap for Asp.Net MVC

Problem:
How do I configure StructureMap for Asp.Net MVC?

Solution:
a. Install StructureMap using NuGet and the following command.

install-package StructureMap.MVC5 

Once StructureMap is installed, you’ll notice several additions to your web project including a new “DependencyResolution” folder.

Dependency Injection

b. Create a new interface. Implement this interface with a new class.

 public interface IDependency
    {
        string SayHelloWorld();
    }
    public class Dependency : IDependency
    {
        public string SayHelloWorld()
        {
            return "Hello World";
        }
    }

c. Have the Controller work with this interface:

public class HomeController : Controller
{
    private readonly IDependency dependency;
    public HomeController(IDependency dependency)
    {
        this.dependency = dependency;
    }
    public ActionResult Index()
    {
        return Content(this.dependency.SayHelloWorld());
    }
}

d. Run your application.The “Concrete Dependency” is successfully injected in HomeController.
Dependency Injection-Results

We didn’t tell StructureMap how to resolve the “IDependency” interface, or let it know anything about the “Dependency” implementation. How did it figure this out?

In the DefaultRegistry.cs file, there is a line of code that reads

scan.WithDefaultConventions();

This code will automatically attempt to resolve any interface named “IDependency” with an instance type named “Dependency”. That is, the same name, but without the “I” prefix. If instead the name of the class was “ConcreteDependency” then the code below will not work. in this case, you will have to specify the types explicitly.You would do that by adding.

For<IDependency>().Use<ConcreteDependency>();

It is commented out in the DefaultRegistry.cs code

public class DefaultRegistry : Registry 
{
        public DefaultRegistry() 
        {
            Scan(
                scan => 
                {
                    scan.TheCallingAssembly();
                    scan.WithDefaultConventions();
                    scan.With(new ControllerConvention());
                });
                //For<IDependency>().Use<ConcreteDependency>();
        }
}
public static class IoC
    {
        public static IContainer Initialize()
        {   
            return new Container(c => c.AddRegistry<DefaultRegistry>());
        }
    }
Continue Reading

Convert the interface of a class into another interface that the clients expects(Adapter Pattern)

Adapter Pattern

Adapter pattern:

    class Program
    {
        static IExpectedInterface dependency = new Adapter(new TargetClass());
        static void Main(string[] args)
        {
            dependency.MethodA();
        }
    }
    public interface IExpectedInterface
    {
        void MethodA();
    }
    public class Adapter : IExpectedInterface
    {
        public Adapter(TargetClass target)
        {
            this.target = target;
        }
        public void MethodA()
        {
            target.MethodB();
        }
        private TargetClass target;
    }
    public class TargetClass
    {
        public void MethodB()
        {
        }
    }

Advantages of using a Adaptor pattern:

  • Adapter pattern lets classes work together that couldn’t otherwise because of incompatible interfaces.
  • The code is more maintainable.
  • most of the applications using third party libraries use adapters as a middle layer between the application and the 3rd party library to decouple the application from the library. If another library has to be used only an adapter for the new library is required without having to change the application code.
Continue Reading