简体   繁体   English

Autofac-如何在接口<>中注册类<,>

[英]Autofac - How to register a class<,> to interface<>

I'm trying to register my repository class which is take two generic parameter to repository interface (one parameter generic). 我正在尝试注册我的存储库类,该类需要两个通用参数到存储库接口(一个通用参数)。

public class RepositoryBase<T, O> : IDataAccess<T>

public interface IDataAccess<T>

Autofac don't know how to set the second generic parameter of RepositoryBase when you only want to provide one generic argument in the interface. 当您只想在接口中提供一个通用参数时,Autofac不知道如何设置RepositoryBase的第二个通用参数。 So you need to somehow specify the second argument in order to instantiate the service unless you are happy with object , dynamic or some base class. 因此,除非您对objectdynamic或某些基类感到满意,否则需要以某种方式指定第二个参数以实例化服务。 In order to achieve this you can create a factory like this: 为此,您可以创建一个如下工厂:

public class BaseRepositoryFactory<T1> : IDataAccessFactory<T1>
{
    private readonly IComponentContext context;

    public BaseRepositoryFactory(IComponentContext context)
    {
        this.context = context;
    }

    public IDataAccess<T1> Create<T2>()
    {
        return context.Resolve<IRepositoryBase<T1, T2>>();
    }
}

public interface IDataAccessFactory<T1>
{
    IDataAccess<T1> Create<T>();
}

public interface IRepositoryBase<T1, T2> : IDataAccess<T1>
{
}

public class RepositoryBase<T1, T2> : IDataAccess<T1>, IRepositoryBase<T1, T2>
{
}

And then register the services like: 然后注册服务,例如:

builder.RegisterGeneric(typeof(BaseRepositoryFactory<>))
    .As(typeof(IDataAccessFactory<>));
builder.RegisterGeneric(typeof(RepositoryBase<,>))
    .As(typeof(IRepositoryBase<,>));

After that you can resolve the factory and create service; 之后,您可以解决工厂问题并创建服务;

var factory = c.Resolve<IDataAccessFactory<string>>();
IDataAccess<string> serviceInterface = factory.Create<int>(); 
var serviceConcrete = (RepositoryBase<string, int>)factory.Create<int>();

So this way you can move the declaration of a second argument to a factory method. 因此,您可以将第二个参数的声明移至工厂方法。 The drawback of this is that you need to create such factories for each type. 这样做的缺点是您需要为每种类型创建此类工厂。 To avoid this you can define additional interface with two generic arugments IDataAccess<T1, T2> and implement it in concrete class and register it so your factory can look like this and will work for any type: 为了避免这种情况,您可以使用两个通用的IDataAccess IDataAccess<T1, T2>定义附加接口,并在具体的类中实现它并注册它,以便您的工厂可以像这样并适用于任何类型:

public class DataAccessFactory<T1> : IDataAccessFactory<T1>
{
    private readonly IComponentContext context;

    public DataAccessFactory(IComponentContext context)
    {
        this.context = context;
    }

    public IDataAccess<T1> Create<T2>()
    {
        return context.Resolve<IDataAccess<T1, T2>>();
    }
}

Try this: 尝试这个:

builder.RegisterGeneric(typeof(RepositoryBase<,>))
         .As(typeof(IDataAccess<>))
         .InstancePerRequest();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM