简体   繁体   中英

Autofac: Registering nested generic Interfaces and classes

I have a DI Autofac in my WebApi project. Autofac cannot resolve. I would like to achieve a situation when I can create new interfaces that implement `IDB to provide new subclass that overrides some methods. I also want to replace DPB with some inherited class in the future.

Here is the code structure:

[RoutePrefix("api/ro")]
public class RODController : ApiController
{
    public RODController(IFO fO, IROD<IDPB> rOD)
    {
        _fO = fO ?? throw new ArgumentNullException(nameof(fO));
        _rOD = rOD ?? throw new ArgumentNullException(nameof(rOD));
    }
}

public interface IROD<T> : IDB<T> where T : IDPB
{ }

public class ROD<T> : DB<T>, IROD<IDPB> where T : IDP
{
    public ROD(IFO fO, T dPB) : base(fO, dPB)
    { }
}

public interface IDB<T> : IDF where T : IDPB
{ }

public abstract class DB<T> : IDB<T> where T : IDPB
{
    protected DB(IFO fO, T dPB)
    {
        _fO = fO ?? throw new ArgumentNullException(nameof(fO));
        _dPB = dPB;
    }
}

public interface IDPB
{ }

public class DPB : IDPB
{ }

public IDF - provide only method to implement by IDB

I have tried code below but with no success

builder.RegisterType<FO>().As<IFO>().InstancePerRequest();
builder.RegisterGeneric(typeof(ROD<>))
    .As(typeof(IROD<>)).InstancePerDependency;
builder.RegisterGeneric(typeof(DB<>))
    .As(typeof(ID<>)).InstancePerDependency();
builder.RegisterType<DPB>().As<IDPB>().InstancePerDependency();

builder.RegisterType<ROD<DPB>>()
    .As<IROD<IDPB>>();

builder.RegisterType<DPB>().As<IDPB>();

The following error is attached below.

None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'ROD`1[DPB]' can be invoked with the available services and parameters: Cannot resolve parameter 'DPB dPB' of constructor 'Void .ctor(IFO, DPB)'.

I wonder because these mappings worked in Unity (ported project).

Edit 1

If I understand you correctly, my answer is yes. I would like to resolve any ROD<T> service of that that implement IDPB . Like in this scenario ROD<T> should be resolved by DPB coming from builder.RegisterType<ROD<DPB>>().As<IROD<IDPB>>();

IROD<IDPB> is a simple way to resolve any dependent class from IDB<T> by different interface name (differentiate from resolving by name).

I simples way in which I can explain my need is to resolve

builder.RegisterType<ROD<DPB>>().As<IROD<IDPB>>();

In Unity <package id="Unity" version="4.0.1" targetFramework="net461" /> a few years late I wrote this that work with this abstract classes.

container.RegisterType<IROD<IDPB>, ROD<DPB>>()

Edit 2

I created a project on github at https://github.com/fruex/StackOverflowAutofac , it generates the same error as described above.

I also prepared a test that directly generates an error ( https://github.com/fruex/StackOverflowAutofac/blob/master/StackOverflowAutofacTest/RODControllerTests.cs ). The URL for this controller is host:port/api/ro/convert

Edit 3

I've added builder.RegisterType(); and it worked.

The exception states that Autofac looks for a type named DPB in the constructor of ROD<T> , but there is no registration for DPB . There is, however, a registration for IDPB that maps to DPB . Did you meant to let ROD<T> depend on IDPB instead?

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