I decided to create a very small IoC container in C# for a MonoGame project. The reason i decided to create one myself is to improve the performance and use less libraries that i don't control. Since IoC is something so simple, i don't think a library should handle it.
I started a naive implementation:
var container = new Container();
container.Register("service-alias",
container => new ServiceClass(container.Resolve("other.dep"));
container.Resolve("service-alias").MethodOnServiceClass()
But I have no idea how to do this in C#'s type system. A Dictionary <string, Func<Container>>
? How do I type the return of the resolve method?
An IOC container allows the declaration of dependencies behind a proxy object. When this happens, we can more easily control whether those dependencies are Transient or Singleton. Having this sort of control lets us open up design opportunities and better UI architecture in our app.
IoC container is a framework for implementing automated dependency injection. It contains object creation for the longer ways to use and injects dependencies within the class.
An IoC container is a common characteristic of frameworks that implement IoC. In the Spring framework, the interface ApplicationContext represents the IoC container. The Spring container is responsible for instantiating, configuring and assembling objects known as beans, as well as managing their life cycles.
Here is an example implementation with 21 lines of code. But please don't be tempted to simplify development by implementing some dictionary that holds the registrations (other than doing so for educational purposes). There are many downsides to hand rolling your own DI library. As explained here, you are much better of by applying Pure DI (which means: DI without DI library) and switching from Pure DI to a DI library later on, in case -and ONLY in case- your Composition Root becomes hard to maintain without.
I really recommend a pragmatic approach here.
1) Design an abstraction for "your dream IoC container", with only the bare minimum that you need. Something like this:
public interface IContainer
{
void RegisterType<TSource, TDestination>();
void RegisterType<TSource>(Func<TSource, TDestination> generator);
T Resolve<T>();
}
2) Create an implementation of your abstraction that simply delegates all the functionality to an existing component. I recommend Autofac but there's plenty of fish in the sea.
3) Develop your application using your "wrapper IoC".
4) If at some point you find that the external IoC component has performance issues (or any other type of issues), write another implementation of your IoC abstraction that uses another external component, your own code, or a combination of both. Even if your application is in an advanced state, you just have to change the small piece of code that instantiates the IoC wrapper (perhaps just one line of code).
Advantages of this approach:
Of course, you will have to make the abstraction grow as you need more advanced functionality. But you should always start with a simple abstraction.
At my work place we are using a more elaborate version of this approach and it's working nicely.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With