简体   繁体   中英

autofac - register generic on non generic abstract class

autofac - register generic on non generic abstract class

I have the following class structures..

public class DataContext<TEntityModel> : DataContextBase
        where TEntityModel : IEntity
    {
        public DataContext(string databaseName, string serverName = "localhost") :
            base(databaseName, serverName)
        {
        }
    }


public abstract class Repository<TEntityModel> : IRepository<TEntityModel>
        where TEntityModel : Entity
    {
        protected MongoRepositoryBase(DataContextBase ctx)
        {
            this.DBContext = ctx;
        }
}

public class CustomerRepository : Repository<Customer>
    {
        public CustomerRepository(DataContext<Customer> ctx)
            : base(ctx)
        {
        }
}

I have tried the following but getting "The type 'Repository 2' does not implement the interface 'IRepository 1'."

builder.RegisterAssemblyTypes(typeof(DataContextBase).Assembly).AsClosedTypesOf(typeof(DataContext<>));

how do i do the IoC registration for DataContext ?

AsClosedTypesOf method won't help you register DataContext<> , by the way it will help you register IRepository<T> .

Instead of registering all your repository manually

    builder.RegisterType<CustomerRepository>().As<IRepository<Customer>>();
    builder.RegisterType<InvoiceRepository>().As<IRepository<Invoice>>();
    ...

You will be able to register all of them once :

    builder.RegisterAssemblyTypes(typeof(IRepository<>).Assembly).AsClosedTypesOf(typeof(IRepository<>)); 

To register DataContext<> in a generic manner you can use a RegistrationSource :

    public class DataContextRegistrationSource : IRegistrationSource
    {

        public Boolean IsAdapterForIndividualComponents
        {
            get { return true; }
        }

        public IEnumerable<IComponentRegistration> RegistrationsFor(Service service, Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor)
        {
            if (service == null)
            {
                throw new ArgumentNullException("service");
            }
            if (registrationAccessor == null)
            {
                throw new ArgumentNullException("registrationAccessor");
            }

            IServiceWithType ts = service as IServiceWithType;
            if (ts == null || !(ts.ServiceType.IsGenericType && ts.ServiceType.GetGenericTypeDefinition() == typeof(DataContext<>)))
            {
                yield break;
            }

            yield return RegistrationBuilder.ForType(ts.ServiceType)
                                            .AsSelf()
                                            .WithParameter(new NamedParameter("databaseName", "test"))
                                            .WithParameter(new NamedParameter("serverName", "test2"))
                                            .CreateRegistration();

        }
    }

Then

    builder.RegisterSource(new DataContextRegistrationSource());

You can now resolve IRepository<Customer>

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