Search code examples
c#dependency-injectionninjectproviderninject-extensions

How to pass an argument to custome provider using ninject


I have a service called MyRepository, I was to write my own custom provider for MyRepository. How can I pass an argument to the constructor of MyRepository using the provider?

This is my code:

public class MyRepository : IMyRepository
{
    private string _path;

    public MyRepository(string path)
    { 
        _path = path;
    }

    // more code...
}

public class MyRepositotyProvider : Provider<IMyRepositoty>
{
    public static IMyRepositoty CreateInstance()
    {
        return new MyRepository(/*how to pass an argument?*/);
    }

    protected override IMyRepositoty CreateInstance(IContext context)
    {
        // I need to pass path argument?
        return CreateInstance();
    }
}

// I need to pass the path argument to the provider
var instance = OrganisationReportPersisterProvider.CreateInstance(/*pass path arg*/);

Solution

  • Based on your comment you could consider using an abstraction that can be passed to lower layers

    public interface ISomeSetting { 
        string Path { get; } 
    }
    

    and can then be resolved via the context in the provider

    public class MyRepositotyProvider : Provider<IMyRepositoty> {
    
        public static IMyRepositoty CreateInstance(string path) {
            return new MyRepository(path);
        }
    
        protected override IMyRepositoty CreateInstance(IContext context) {
            ISomeSetting setting = context.Kernel.Get<ISomeSetting>()
            var path = setting.Path;
            return CreateInstance(path);
        }
    }
    

    The implementation will live in a higher layer and allows for decoupling.

    Ideally the repository could have been refactored to depend on the abstraction

    public class MyRepository : IMyRepository {
        private readonly string _path;
    
        public MyRepository(ISomeSetting setting)  
            _path = setting.Path;
        }
    
        // more code...
    }
    

    and avoid the need to have a provider to begin with.