C# 使用 Autofac 注册部分封闭的泛型类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15226536/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 14:32:40  来源:igfitidea点击:

Register partically closed generic type with Autofac

c#genericsautofacunit-of-work

提问by shortcode

I have UnitofWorkclass and it implement IUnitOfWork. I try to register that with Autofac:

我有UnitofWork课,它实现了IUnitOfWork. 我尝试用 Autofac 注册它:

var builder = new ContainerBuilder();
builder
    .RegisterGeneric(typeof(UnitOfWork<Repository<>,>))
    .As(typeof(IUnitOfWork))
    .InstancePerDependency();

Implementation is:

实现是:

public class UnitOfWork<T, O> : IUnitOfWork
    where T : Repository<O>
    where O : BaseEntity
{
}

public interface IUnitOfWork : IDisposable
{
    void SaveChanges();
}

Gives an error "Type expected"

给出错误“预期类型”

but this one work on another project:

但是这个在另一个项目上工作:

public class Repository<T> : GenericRepository<T> 
    where T : BaseEntity
{
    public Repository(IDbContext context) : base(context) { }   
}

public abstract class GenericRepository<T> 
    : IRepository<T>, IQueryable<T> where T : BaseEntity
{
}

builder
    .RegisterGeneric(typeof(Repository<>))
    .As(typeof(IRepository<>))
    .InstancePerHttpRequest();

采纳答案by nemesv

You cannot have partially opened classes(e.g. with UnitOfWork<Repository<>,>you have specified Tbut not O) inside a typeof, try it with:

不能有部分打开类(例如,用UnitOfWork<Repository<>,>您指定T,但没有O里面typeof,有尝试:

var builder = new ContainerBuilder();
builder
    .RegisterGeneric(typeof(UnitOfWork<,>))
    .As(typeof(IUnitOfWork))
    .InstancePerDependency();

The where T : Repository<O>generic constraint will take care of that the first argument should be an Repository<>

where T : Repository<O>通用的限制将采取的第一个参数应该是一个照顾Repository<>

But it won't work with RegisterGenericbecause it requires a generic interfaceso need to create a IUnitOfWork<T,O>

但它不会工作,RegisterGeneric因为它需要一个通用接口,所以需要创建一个IUnitOfWork<T,O>......

But your model is very strange. Why does your UnitOfWorkneed a Repository<>type argument?

但是你的模型很奇怪。为什么UnitOfWork需要Repository<>类型参数?

Instead of having it as a type argument you can get an Repository<>in your UnitOfWork<E>constructor:

您可以Repository<>UnitOfWork<E>构造函数中获取一个,而不是将其作为类型参数:

public class UnitOfWork<E> : IUnitOfWork<E> where E : BaseEntity
{
    private readonly Repository<E> repository;

    public UnitOfWork(Repository<E> repository)
    {
        this.repository = repository;
    }

    //.. other methods

}

Where IUnitOfWork<E>

在哪里 IUnitOfWork<E>

public interface IUnitOfWork<E> : IDisposable where E : BaseEntity
{
    void SaveChanges();
}

And the Autofac registration:

和 Autofac 注册:

var builder = new ContainerBuilder();
builder
    .RegisterGeneric(typeof(Repository<>)).AsSelf();
builder
    .RegisterGeneric(typeof(UnitOfWork<>))
    .As(typeof(IUnitOfWork<>))
    .InstancePerDependency();
var container = builder.Build();

// sample usage
var u = container.Resolve<IUnitOfWork<MyEntity>>();