Achieving DI without a third-party structure

I am writing a plugin as part of the plugin architecture. The way to create plugins is through reflection and CreateInstance . Therefore, the default constructor is called. I cannot touch this code, and I am trying to find a reasonable way to use DI without the ability to use a framework.

I believe that I have 3 options:

i) Poor DI (PMDI)

ii) Factory Template

iii) TinyIOC or similar (one cs file that processes DI)

I started to study PMDI, but then the dependent needed another dependency, so I got something similar to this, which was ugly and could get worse:

 public MyMainPluginClass() : this(new Repo(new Logger())) { } public MyMainPluginClass(IRepo repo) { } 

Then I moved on to the idea of ​​the Factory template, but could not find a decent demo code. I assume that I will have something like this:

 public static FactoryUtility { public static IRepo GetRepo() { return new Repo(GetLogger()); } public static ILogger GetLogger() { return new Logger(); } } public MyMainPluginClass() : this(FactoryUtility.GetRepo()) { } public MyMainPluginClass(IRepo repo) { } 

What does it look like?

Then I stumbled upon TinyIOC , which is one class that does all the registration of dependencies, but I believe that this requires installing in the program .cs, which I do not have in the class library. If anyone has experience using this, it can be used like this:

  public MyMainPluginClass() { var container = TinyIoCContainer.Current; container.AutoRegister(); var implementation = container.Resolve<IRepo>(); MyMainPluginClass(implementation); } public MyMainPluginClass(IRepo repo) { } 

Are there any alternative approaches to achieve DI without using a third-party library, and if any approach were not chosen from the above?

NOTE. . The above code has not been compiled and is just an idea of ​​what, in my opinion, will work. Please make corrections if they are valid.

+4
source share
3 answers

I went with TinyIOC at the end. Unfortunately, the plugin constructor is called several times before it actually starts and runs. I just set a boolean value to prevent the registration being called multiple times, and therefore it allows me to simply automatically register dependencies and exit.

 public MyMainPluginClass() : this(FactoryUtility.SetupIOC()) { } public MyMainPluginClass(IRepo repo) { } public static class FactoryUtility { private static bool Initialized = false; public static IRepo SetupIOC() { var container = TinyIoCContainer.Current; if (!Initialized) { container.AutoRegister(new[] { Assembly.GetExecutingAssembly() }); Initialized = true; } var result = container.Resolve<IRepo>(); return result; } } 
+1
source

Since you are using .NET 4, you may need to use MEF as it is built into the environment itself. This is similar to a fairly simple DI that MEF handles well, as it is primarily intended for extensibility.

For more information, see the Read More page on the MEF CodePlex website .

+2
source

If I absolutely do not want to add dependency to the DI container, I like to use my own TinyIOC (sorry for the name, I do not know what it was done), which for small projects gives me the same semantics as using the container, but the clock is below 200 LOC.

If you're interested, here is the code: https://gist.github.com/ad7608e2ae10b0f04229

0
source

Source: https://habr.com/ru/post/1396287/


All Articles