Search code examples
c#design-patternsdependency-injectionarchitecture

Is it a good practice to inject a factory to a class to can create some resources?


I have an application that use a XML file to define some remote servers from where I want to request some files.

I use the XML file because I can set N number of servers with N number of files to be requested, so I don't know in code how many servers I will have.

This is the code:

public class Application : IApplication
{
    private readonly List<Requester> _requesters = [];

    public Application(IRequesterFactory paramRequesterFactory)
    {
        _requesters.AddRange(paramRequesterFactory.GetRequesters());
    }



    public RequestFiles()
    {
        foreach(Requester requester in _requesters)
        {
            _requsters.RequestFiles();
        }
    }
}


public class RequesterFactory
{
    private readonly ICongigurationManager _configurationManager;


    public RequesterFactory(IConfigurationManager paramConfigurationManager)
    {
        _configurationManager = paramConfigurationManager;
    }



    public List<Requester> CreateRequesters()
    {
        //Create requesters from the information getted from the configuration XML file using cofiguration manager.
    }
}

But my doubt if it is a good idea to inject a factory in the class so this class can get the requesters that it needs.

Depedency injection, if I am not wrong, it is used to avoid the self class create the resources that it needs to work.

But in this way, it uses a factory that is passed as interface, so I can pass any other implementation and I can test the class, that is one of the benefits of IoC.

In theory it seems that the class is creating the objetcs that it needs, but how I am using and interface as factory, I think I am using the benefits of dependency injection.

So my quesetion is, is it a good proactice to inject a factory to a class how I am doing? How could I use dependency injection to can create N objetcs that can be different or modify thorugh the XML file?

Thanks.


Solution

  • In theory it seems that the class is creating the objects that it needs

    Not exactly, it requests another one (the factory) to create them and you can decide on the concrete factory on the composition root level.

    The factory pattern which you are using is a well-known one and it pairs with DI very nicely. The framework-provided infrastructure includes some factories too. Like IHttpClientFactory for example or IDbContextFactory in EF Core.

    Depending on the actual app you might want to consider abstracting the Requester via an interface too:

    interface IRequesterFactory
    {
        public IReadOnlyCollection<IRequester> CreateRequesters();
    }
    

    Note: quite often the factory approach is designed so the DI container does not control the lifetime of the factory-created object so if it should be disposed then you will need to do that "manually" (see the DbContext and HTTP factory examples), though it not always can be the case so sometimes this can cause a leaky abstraction.