简体   繁体   中英

Achieving DI without 3rd party framework

I am writing a plugin as part of a plugin architecture. The way plugins are created is via reflection and CreateInstance . Therefore the default constructor is called. This code I cannot touch and I am trying to find a sensible way to use DI without the ability to use a framework.

I believe I have 3 options:

i) Poor Man's DI (PMDI)

ii) Factory Pattern

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

I started looking at PMDI but then a dependency needed another dependency so I ended up with something similar to this which is ugly and could get worse:

public MyMainPluginClass() : this(new Repo(new Logger()))
{

}

public MyMainPluginClass(IRepo repo)
{

}

I then moved onto the idea of a Factory Pattern but could not find any decent demo code. I assume I would 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)
    {

    }

Is that how it would look?

I then came across TinyIOC which is one class that does all the dependency registering but I believe it requires to be setup in a Program.cs which I don't have in a class library. If someone has any experience using this could it be used like so:

    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 3rd party library and if not which approach would choose from above?

NOTE: The code above has not been compiled and is just an idea of what I think would work. Please post corrections if they are valid approaches.

Since you're using .NET 4, you might want to consider using MEF, as it's built into the framework itself. This looks like fairly straightforward DI, which MEF handles well, as it's intended mainly for extensibility.

For details, see the Learn More page on the MEF CodePlex site .

I went with TinyIOC in the end. Unfortunately the plugin's constructor gets called several times before its actually up and running. I simply set a boolean to prevent registration being called several times and therefore it allows me to simply auto-register dependencies and off we go.

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;
    }
}

If I absolutely don't want to add a dependency to a DI container, I like to use my own TinyIOC (sorry about the name, didn't know it was taken), which for small projects gives me the same semantics as using a container, but clocks in at below 200 LOC.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM