Thursday, April 27, 2017

Creating an IOC Container for ASP.NET Core

I recently added support for ASP.NET Core to my Tact.NET IOC Container, and I thought that I would share some of the interesting requirements I discovered while doing so. I had originally expected the default ASP.NET Core container would follow the same rules as the official Microsoft Unity container, but that turned out not to be the case!

1) Register is first in win.

The Unity container was last in win, and it would completely disregard the original registration. With ASP.NET Core you need to preserve the original registration and then treat all subsequent registrations as addition registrations that will only be resolved when ResolveAll is invoked, similar to keyed registrations in Unity. Which brings us to our next difference...

public class RegisterIsFirstInWinTests
{
    [Fact]
    public void Unity()
    {
        var log = new EmptyLog();
        using (var container = new TactContainer(log))
        {
            container.RegisterSingleton<IExample, ExampleA>();
            container.RegisterSingleton<IExample, ExampleB>();
 
            var example = container.Resolve<IExample>();
            Assert.IsType<ExampleB>(example);
        }
    }
 
    [Fact]
    public void AspNetCore()
    {
        var log = new EmptyLog();
        using (var container = new AspNetCoreContainer(log))
        {
            container.RegisterSingleton<IExample, ExampleA>();
            container.RegisterSingleton<IExample, ExampleB>();
 
            var example = container.Resolve<IExample>();
            Assert.IsType<ExampleA>(example);
        }
    }
 
    public interface IExample
    {
        string Name { get; }
    }
 
    public class ExampleA : IExample
    {
        public string Name => nameof(ExampleA);
    }
 
    public class ExampleB : IExample
    {
        public string Name => nameof(ExampleB);
    }
}

2) ResolveAll includes single registrations.

Unity has the concept of keyed registrations, where you can register the same type multiple times with distinct keys (strings) and then resolve them individually by key or as an IEnumerable with ResolveAll. In ASP.NET Core there is no concept of keyed registration, and ResolveAll will return all registrations made for a given type. This means that registering a single type will cause ResolveAll to return an IEnumerable with one value.

public class ResolveAllIncludesSingleRegistrations
{
    [Fact]
    public void Unity()
    {
        var log = new EmptyLog();
        using (var container = new TactContainer(log))
        {
            container.RegisterSingleton<IExample, ExampleA>();
            container.RegisterSingleton<IExample, ExampleB>();
 
            var examples = container.ResolveAll<IExample>();
            Assert.Equal(0, examples.Count());
        }
    }
 
    [Fact]
    public void AspNetCore()
    {
        var log = new EmptyLog();
        using (var container = new AspNetCoreContainer(log))
        {
            container.RegisterSingleton<IExample, ExampleA>();
            container.RegisterSingleton<IExample, ExampleB>();
 
            var examples = container.ResolveAll<IExample>();
            Assert.Equal(2, examples.Count());
            }
    }
 
    public interface IExample
    {
        string Name { get; }
    }
 
    public class ExampleA : IExample
    {
        public string Name => nameof(ExampleA);
    }
 
    public class ExampleB : IExample
    {
        public string Name => nameof(ExampleB);
    }
}

3) Generic resolution is required.

This was a neat feature that I had not used before! You can register generic types without any generic parameters, and then the container will fill in the generic parameters based on the resolve request. So, for example, I could register IRepository<> to type DataRepository<>, and then when I call container.Resolve<IRepository<User>>, the IOC container will automatically try to construct a DataRepository<User>

public class TactContainerTests
{
    [Fact]
    public void GenericResolution()
    {
        var log = new EmptyLog();
        using (var container = new TactContainer(log))
        {
            container.RegisterSingleton(typeof(IRepository<>), typeof(Repository<>));
 
            var userRepository = container.Resolve<IRepository<User>>();
            Assert.IsType<Repository<User>>(userRepository);
        }
    }
 
    public interface IRepository<T>
    {
        string ClassName { get; }
        string GenericName { get; }
    }
 
    public class Repository<T> : IRepository<T>
    {
        public string ClassName => nameof(Repository<T>);
        public string GenericName => typeof(T).Name;
    }
 
    public class User
    {
    }
}

4) You have to convert IServiceCollection to your container.

I like how the new .NET separates their service registration from the container itself. In your ASP.NET Core wire up you will work with an IServiceCollection, which will then be converted into a container after you are done filling in your registrations. This means that if you want to create your own container, you will need to map the service collection into your container.

Enjoy,
Tom

10 comments:

  1. You’ve written a really great article here. Your writing style makes this material easy to understand.. I agree with some of the many points you have made. Thank you for this is real thought-provoking content.
    MSBI Online Training
    MSBI Online Certification
    Learn MSBI Course

    ReplyDelete
    Replies
    1. The development of artificial intelligence (AI) has propelled more programming architects, information scientists, and different experts to investigate the plausibility of a vocation in machine learning. Notwithstanding, a few newcomers will in general spotlight a lot on hypothesis and insufficient on commonsense application. machine learning projects for final year In case you will succeed, you have to begin building machine learning projects in the near future.

      Projects assist you with improving your applied ML skills rapidly while allowing you to investigate an intriguing point. Furthermore, you can include projects into your portfolio, making it simpler to get a vocation, discover cool profession openings, and Final Year Project Centers in Chennai even arrange a more significant compensation.

      Data analytics is the study of dissecting crude data so as to make decisions about that data. Data analytics advances and procedures are generally utilized in business ventures to empower associations to settle on progressively Python Training in Chennai educated business choices. In the present worldwide commercial center, it isn't sufficient to assemble data and do the math; you should realize how to apply that data to genuine situations such that will affect conduct. In the program you will initially gain proficiency with the specialized skills, including R and Python dialects most usually utilized in data analytics programming and usage; Python Training in Chennai at that point center around the commonsense application, in view of genuine business issues in a scope of industry segments, for example, wellbeing, promoting and account.

      The Nodejs Projects Angular Training covers a wide range of topics including Components, Angular Directives, Angular Services, Pipes, security fundamentals, Routing, and Angular programmability. The new Angular TRaining will lay the foundation you need to specialise in Single Page Application developer. Angular Training

      Delete
  2. Good Post! , it was so good to read and useful to improve my knowledge as an updated one, keep blogging.After seeing your article I want to say that also a well-written article with some very good information which is very useful for the readers....thanks for sharing it and do share more posts likethis. https://www.3ritechnologies.com/course/data-science-online-training/

    ReplyDelete
  3. Good day! Would you mind if I share your blog with my facebook group?
    There’s a lot of people that I think would really appreciate your content.
    Please let me know. Cheers

    IB KEYGEN

    ccleaner pro crack

    ReplyDelete
  4. It is helpful for me. It is informative. I think you are the best blogger. so thanks for sharing the informative article. World wide Marketing Agency

    Driver Booster Pro Crack

    Pilotedit Crack

    Download Cracks for PCs

    IDM Crack

    Tomabo MP4 Downloader Pro Crack

    World of Cracks

    ReplyDelete
  5. Hello I am" 토토사이트 ". I think my writing will be helpful to you, so I leave it like this. Your writing also helped me. It looks like we will help each other.

    ReplyDelete
  6. Autobrix is the best automotive that provides doorstep services for cars and bikes.Book the services through the website and the expert mechanic will inspect your vehicles at your doorstep.

    ReplyDelete

Real Time Web Analytics