Dependency container and C # constructors

I spent some time on documentation on dependency injection and IoC, but I did not find a solution for my problem.

My problem is creating objects when using the dependency container in the sense that it creates a dependency on the constructor arguments. In almost all the examples I came across, the constructors of specific classes have no arguments. This makes everything pretty β€œsimple." Hence my question.

Take an example: I need to load some data from two sources A and B. Source A contains data in a different format; e.g. csv and xml. We do not need to indicate such a thing for source B.

Here is some code (note that I simplified the code as much as I could to illustrate my point):

using System.Net;
using System.IO;
using System.Reflection;

namespace Question
{
  class Program
  {
    static void Main(string[] args)
    {
        //exemple of code using Client A
        DependencyContainer container1 = GetContainer1();
        IClient client1 = container1.Resolve<IClient>("xml");
        User user1 = new User(client1);
        user1.run();

        DependencyContainer container2 = GetContainer2();
        IClient client2 = container2.Resolve<IClient>();
        User user2 = new User(client2);
        user2.run();
    }

    public static DependencyContainer GetContainer1()
    {
        DependencyContainer container = new DependencyContainer();
        container.Register<IClient, ClientA>();
        return container;
    }

    public static DependencyContainer GetContainer2()
    {
        DependencyContainer container = new DependencyContainer();
        container.Register<IClient, ClientB>();
        return container;
    }
}

public class User
{
    private readonly IClient _Client;

    public User(IClient client)
    {
        _Client = client;
    }

    public void run()
    {
        string address = _Client.getAddress();
        string data = _Client.getData(address);
        _Client.writeData(data);
    }
}
// Abstraction
public interface IClient
{
    /// <summary>
    /// create the address or the name of the file storing the data
    /// </summary>
    string getAddress();

    /// <summary>
    /// uses a WebClient to go and get the data at the address indicated
    /// </summary>
    string getData(string adress);

    /// <summary>
    /// Write the data in a local folder
    /// </summary>
    void writeData(string data);
}

//Implementation A
public class ClientA : IClient
{
    // Specify the type of the file to be queried in the database
    // could be a csv or an xml for example
    private readonly string _FileType;

    public ClientA(string fileType)
    {
        _FileType = fileType;
    }

    public string getAddress()
    {
        return "addressOfFileContainingData." + _FileType;
    }

    public string getData(string address)
    {
        string data = string.Empty;
        using (WebClient client = new WebClient())
        {
            data = client.DownloadString(address);
        }
        return data;
    }

    public void writeData(string data)
    {
        string localAddress = "C:/Temp/";
        using (StreamWriter writer = new StreamWriter(localAddress))
        {
            writer.Write(data);
        }
    }
}

//Implementation B
public class ClientB : IClient
{
    public ClientB()
    {
    }

    public string getAddress()
    {
        return "addressOfFileContainingData";
    }

    public string getData(string address)
    {
        string data = string.Empty;
        using (WebClient client = new WebClient())
        {
            data = client.DownloadString(address);
        }
        return data;
    }

    public void writeData(string data)
    {
        string localAddress = "C:/Temp/";
        using (StreamWriter writer = new StreamWriter(localAddress))
        {
            writer.Write(data);
        }
    }
}

public class DependencyContainer
{
    private Dictionary<Type, Type> _Map = new Dictionary<Type, Type>();

    public void Register<TypeToResolve, ResolvedType>()
    {
        _Map.Add(typeof(TypeToResolve), typeof(ResolvedType));
    }

    public T Resolve<T>(params object[] constructorParameters)
    {
        return (T)Resolve(typeof(T), constructorParameters);
    }

    public object Resolve(Type typeToResolve, params object[] constructorParameters)
    {
        Type resolvedType = _Map[typeToResolve];
        ConstructorInfo ctorInfo = resolvedType.GetConstructors().First();
        object retObject = ctorInfo.Invoke(constructorParameters);
        return retObject;
    }
}

}

, , . , :

IClient client = container.Resolve<IClient>("xml");

IClient client = container.Resolve<IClient>();

. ( User ) , . ! , - . , . , ClientA , , , .

, :

  • IoC?
  • ?
  • , ?

ClientA. , ? , ? , ClientA ClientB , .

.

+4
1

IoC?

. , (User, ClientA, ClientB) , (DI). DI, , .

, Pure DI, Main :

static void Main(string[] args)
{
    //exemple of code using Client A
    User user1 =
       new User(
           new ClientA(
               "xml"));
    user1.run();

    User user2 =
        new User(
            new ClientB());
    user2.run();
}

, .

DI , , Injection.

?

, , . DI Pure DI, Register Resolve Release. User, IClient:

var user = container.Resolve<User>();
user.run();

. ClientA, , fileType. , , DI, .

, , , .

, ?

Pure DI, DI. , .

+7

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


All Articles