简体   繁体   中英

Autofac - Register Abstract Generic Class Failure

In my business layer. I want to make an abstract class and implement by all my entity manager classes.

So I have an error like this.

None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'x.Business.Concrete.DepartmentManager' can be invoked with the available services and parameters: Cannot resolve parameter 'x.Core.DataAccess.IDataAccess 1[x.Entities.Concrete.Department] dataAccess' of constructor 'Void .ctor(x.Core.DataAccess.IDataAccess 1[x.Entities.Concrete.Department])'.

error image

After a little bit change.

IDataAccess.cs

public interface IDataAccess<T>

Data Access Layer

IDepartmentDAL.cs

public interface IDepartmentDAL : IDataAccess<DPT_DEPARTMENT>

EntityFrameworkEntityRepositoryBase.cs

public class EfEntityRepositoryBase<TEntity, TContext> : IDataAccess<TEntity>

EntityFrameworkDepartmentDAL.cs

public class EfDepartmentDAL : EfEntityRepositoryBase<DPT_DEPARTMENT, Context>, IDepartmentDAL

Business Logic Layer

ServiceBase.cs

 public abstract class ServiceBase<T> : IDataAccess<T> 
    {
        public IDataAccess<T> _dataAccess;
        public ServiceBase(IDataAccess<T> dataAccess)
        {
            _dataAccess = dataAccess;
        }
    }

DeparmentManager.cs

public class DepartmentManager : ServiceBase<Department>
    {
        public DepartmentManager(IDataAccess<Department> dataAccess) : base(dataAccess)
        {
        }
    }

Configuration

AutofacModule.cs

protected override void Load(ContainerBuilder builder)
{
    builder.RegisterAssemblyTypes(typeof(ServiceBase<>).Assembly).AsClosedTypesOf(typeof(ServiceBase<>)).InstancePerLifetimeScope();

    builder.RegisterAssemblyTypes(System.Reflection.Assembly.Load("x.DataAccess"))
           .Where(t => t.Name.StartsWith("Ef") && t.Name.EndsWith("DAL"))
           .AsImplementedInterfaces()
           .InstancePerLifetimeScope();

    //builder.RegisterType(typeof(EfEntityRepositoryBase<,>)).As(typeof(IDataAccess<>)).InstancePerRequest();
    //builder.RegisterAssemblyTypes(typeof(EfEntityRepositoryBase<,>).Assembly).AsImplementedInterfaces().InstancePerLifetimeScope();
    //builder.RegisterGeneric(typeof(EfEntityRepositoryBase<,>)).AsSelf();
    //builder.RegisterGeneric(typeof(EfEntityRepositoryBase<,>)).AsImplementedInterfaces().InstancePerLifetimeScope();
    builder.RegisterType(typeof(AssessmentContext)).As(typeof(DbContext)).InstancePerLifetimeScope();
    builder.RegisterGeneric(typeof(EfEntityRepositoryBase<,>)).As(typeof(IDataAccess<>)).InstancePerRequest();
}

So, how should I register my types to autofac container. I tried many of other topics as you can see the comment lines on my configuration class and could not find any solution.

The error message is telling you that Autofac failed to instantiate DepartmentManager , because it doesn't know what to use for the dataAccess argument. The type of that argument is IDataAccess<Department> .

To fix this, you need to register a type as providing a IDataAccess<Department> implementation.

It looks like you have a generic type EfEntityRepositoryBase<TEntity, TContext> which could be used like that. You seem to have done some attempts to register that class, but you did not fill in the type parameters and autofac can't do that for you. You could probably register it like this:

builder.RegisterType<EfEntityRepositoryBase<Department,DepartmentContext>>()
    .As<IDataAccess<Department>>()
    .InstancePerLifetimeScope();

(I just assumed that there was something like DepartmentContext for the TContext type parameter.)

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