使用Unity,你如何注册泛型的类型映射? [英] Using Unity, how do you register type mappings for generics?

查看:696
本文介绍了使用Unity,你如何注册泛型的类型映射?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图实现一个存储库解决方案,但是使用Unity可以注册包含泛型的类型。



给定:

  // IRepository interface 
public接口IRepository< TEntity>
{
//为简洁而省略
}

//存储库实现
public class Repository< TEntity,TContext> :IRepository< TEntity> IDisposable
其中TEntity:class
其中TContext:DbContext
{
//为简洁而省略
}

//服务层构造函数
public MyServiceConstructor(IRepository< Account> repository)
{
_repository = repository;
}

我需要注册IRepository到Repository的类型映射。但是我遇到了这种映射的Unity语法问题。



我没有运气尝试过以下操作:

  container.RegisterType< IRepository>,typeof(Repository>)>(); 
container.RegisterType< typeof(IRepository<),Repository<,>>();

编辑



基于@Steven响应我现在有以下实现:

  // UnityRepository实现
public class UnityRepository< ; TEntity> :存储库< TEntity,MyDbContextEntities>
其中TEntity:class
{
public UnityRepository():base(new MyDbContextEntities()){}
}

// Unity bootstrapper
container.RegisterType(typeof(IRepository&s)),typeof(UnityRepository));


解决方案

您正在尝试执行以下操作:

  container.RegisterType(typeof(IRepository<)),typeof(Repository<,>)); 

这通常可以工作,但是在这种情况下不会这样做,因为有code> IRepository< TEntity> 有一个通用参数, Repository< TEntity,TContext> 有两个,Unity(显然)猜你应该填写什么类型的 TContext



你需要的是这样的:

  container.RegisterType(
typeof(IRepository<)),
typeof(Repository< MyDbContextEntities>));

换句话说,你想提供 Repository< TEntity, TContext> 作为部分打开的通用类型(填有一个参数)。不幸的是,C#编译器不支持这一点。



但即使C#确实支持这一点,Unity不支持部分打开的泛型类型。实际上大多数IoC库eworks不支持这一点。而对于那个支持它的一个库,您仍然需要做以下(讨厌的事情)来创建部分打开通用类型:

 键入myDbContextEntitiesRepositoryType = 
typeof(Repository<,>)MakeGenericType(
typeof (Repository<,>)。GetGenericParameters()。First(),
typeof(MyDbContextEntities));

有一个简单的技巧可以解决这个问题:define一个通用类型的派生类:

  //组合根中的特殊实现
public class UnityRepository< TEntity> :存储库< TEntity,MyDbContextEntities>
其中TEntity:class
{
public UnityRepository([dependencies]):base([dependencies]){}
}
/ pre>

现在我们可以轻松地注册这个打开的泛型类型:

  container.RegisterType(typeof(IRepository<)),typeof(UnityRepository<>)); 


I'm trying to implement a repository solution for Entity Framework but I am having trouble registering the types that include generics using Unity.

Given:

    // IRepository interface
    public interface IRepository<TEntity>
    {
        // omitted for brevity
    }

    // Repository implementation
    public class Repository<TEntity, TContext> : IRepository<TEntity>, IDisposable 
            where TEntity : class
            where TContext : DbContext
    {
        // omitted for brevity
    }

    // service layer constructor
    public MyServiceConstructor(IRepository<Account> repository)
    {
        _repository = repository;
    }

I need to register the type mapping for IRepository to Repository. but I'm having trouble with the Unity syntax for this kind of mapping.

I have tried the following with no luck:

container.RegisterType<IRepository<>, typeof(Repository<,>)>();
container.RegisterType<typeof(IRepository<>), Repository<,>>();

EDIT

Based, on @Steven response I have the following implementation now:

// UnityRepository implementation   
public class UnityRepository<TEntity> : Repository<TEntity, MyDbContextEntities>
        where TEntity : class
{
    public UnityRepository() : base(new MyDbContextEntities()) { }
}

// Unity bootstrapper
container.RegisterType(typeof(IRepository<>), typeof(UnityRepository<>));

解决方案

You are trying to do the following:

container.RegisterType(typeof(IRepository<>), typeof(Repository<,>));

This would normally work, but won't do the trick in this case, since there is IRepository<TEntity> has one generic argument and Repository<TEntity, TContext> has two, and Unity (obviously) can't guess what type it should fill in for TContext.

What you need is this:

container.RegisterType(
    typeof(IRepository<>),
    typeof(Repository<, MyDbContextEntities>));

In other words, you'd want to supply the Repository<TEntity, TContext> as a partial open generic type (with one parameter filled in). Unfortunately, the C# compiler does not support this.

But even if the C# did support this, Unity doesn't support partial open generic types. In fact most IoC libraries eworks don't support this. And for that one library that does support it, you would still have to do the following (nasty thing) to create the partial open generic type:

Type myDbContextEntitiesRepositoryType =
    typeof(Repository<,>).MakeGenericType(
        typeof(Repository<,>).GetGenericParameters().First(),
        typeof(MyDbContextEntities));

There's a easy trick work around to get this to work though: define a derived class with one generic type:

// Special implementation inside your Composition Root
public class UnityRepository<TEntity> : Repository<TEntity, MyDbContextEntities>
        where TEntity : class
{
    public UnityRepository([dependencies]) : base([dependencies]) { }
}

Now we can easily register this open generic type:

container.RegisterType(typeof(IRepository<>), typeof(UnityRepository<>));

这篇关于使用Unity,你如何注册泛型的类型映射?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆