Is it possible to use Property Injection with Nancyfx default TinyIoc container?

851 views Asked by At

Yes I know, it is better to use Constructor Injection and I do use it most of the time but, there is this one scenario where I like to use Property Injection:

I have a repository base class which has dependencies of a database factory and also a service to read app settings (abstraction of ConfigurationManager)

public abstract class RepositoryBase(){
    public IDatabaseFactory DatabaseFactory { get; set; }
    public IAppConfigService AppConfig { get; set; }

    protected Database Db 
    {
        get
        {
            var db = DatabaseFactory.Get();
            ... not relevant code ...
            return db;
        }
    }
}

I don't want to use constructor dependencies here because this will force me to add constructors to all my repositories, I could do it, but I don't want to. Even worse issue is if for some reason I add a log service to the RespositoryBase class I'll have to add this new dependency to the constructor of all my repository classes, this is not cool.

I could use some pattern like service aggregation to avoid modifying the RepositoryBase class, but this just seems too complicated and I really like to keep things simple so everybody can understand what is going on (including me).

So, is it possible to have these dependencies injected by Nancy / TinyIOC?

2

There are 2 answers

0
Alexandr On BEST ANSWER

If we look into the TinyIoC's code we will find what where is no properties injection code after the object creation: https://github.com/NancyFx/Nancy/blob/master/src/Nancy/TinyIoc/TinyIoC.cs#L3693 and in the original repo too: https://github.com/grumpydev/TinyIoC/blob/master/src/TinyIoC/TinyIoC.cs#L3849

If we patch the code with something like that:

        try
        {
            object o = null;
#if USE_OBJECT_CONSTRUCTOR
            var constructionDelegate = CreateObjectConstructionDelegateWithCache(constructor);
            o = constructionDelegate.Invoke(args);
#else
            o = constructor.Invoke(args);
#endif
            BuildUp(o, ResolveOptions.Default);

            return o;
        }
        catch (Exception ex)
        {
            throw new TinyIoCResolutionException(typeToConstruct, ex);
        }

it will work but we will get another problems. The main problem is BuildUp will try to fill the all null references it will find. And there is no appropiate ResolveOptions to avoid this:( Am I right?

...

Finally I created the Inject attribute. You can mark any reference-type property with [Inject] and you will get the desired behavior.

The source is available here: https://github.com/AIexandr/Nancy/blob/master/src/Nancy/TinyIoc/TinyIoC.cs All changes are backward compatible.

2
Christian Horsdal On

Yes, TinyIoC supports property injection. This should work in Nancy as well.