解决通用服务

时间:2010-10-04 19:15:02

标签: .net dependency-injection ioc-container generics autofac

我得到了以下服务:

IRepository<TEntity, TPrimaryKey>

..我为其创建了一个定义为:

的实现
Repository<TEntity, TPrimaryKey>.

如何在autofac中注册它,以便我可以将其解析为:

IRepository<User, int>

2 个答案:

答案 0 :(得分:4)

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

我喜欢autofac。

答案 1 :(得分:0)

作为您自己的解决方案的替代方案,您可以尝试定义用于创建新存储库实例的工厂:

public interface IRepositoryFactory
{
    IRepository<TEntity, TPrimaryKey> 
        CreateRepository<TEntity, TPrimaryKey>();

    // Perhaps other overloads here
}

internal class RepositoryFactory : IRepositoryFactory
{
    public IContainer Container { get; set; }

    public IRepository<TEntity, TPrimaryKey> 
        CreateRepository<TEntity, TPrimaryKey>()
    {
        return container.Resolve<Repository<TEntity, TPrimaryKey>>();
    }
}

您可以按如下方式注册RepositoryFactory

builder.Register(c => new RepositoryFactory() { Container = c })
    .As<IRepositoryFactory>()
    .SingleInstance();

现在您可以将IRepositoryFactory声明为构造函数参数并创建新实例。查看此ProcessUserAccountUpgradeCommand类的实例,该类对其依赖项使用依赖注入:

public ProcessUserAccountUpgradeCommand : ServiceCommand
{
    private readonly IRepositoryFactory factory;

    ProcessUserAccountUpgradeCommand(IRepositoryFactory factory)
    {
        this.factory = factory;
    }

    protected override void ExecuteInternal()
    {
        // Just call the factory to get a repository.
        var repository = this.factory.CreateRepository<User, int>();

        User user = repository.GetByKey(5);
    }
}

虽然使用工厂而不是直接获取存储库似乎有点麻烦,但您的设计将清楚地传达检索到的新实例(因为您调用CreateRepository方法)。从IoC容器返回的实例通常为expected to have a long life

另一个提示:您可能想要重构主键类型的使用。总是要求<User, int>而不仅仅是<User>存储库的存储库会很麻烦。也许你找到了一种在工厂内抽象出主键的方法。

我希望这会有所帮助。