仿制药&静态类。实现查询帮助器方法 [英] Generics & static classes. Implement query helper method

查看:234
本文介绍了仿制药&静态类。实现查询帮助器方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前我们实现了一个像这样的映射服务(该服务使用了automapper,并且我们利用它的投影功能来完成这部分)

  //注入
// IGenericRepository< Entity> entityRepo

var query = this.entityRepo
.FindAll(a => a.Id == someId)
.Take(1);

var result = this.mappingService
.Map< Entity,EntityDto>(query)
.FirstOrDefault();

我想创建一个扩展名,允许我执行以下操作 strong>

  var result = this.entityRepo 
.FindAll(a => a.Id == someId)
.Take(1).Map< EntityDto>()< ---从回购类型
.FirstOrDefault()推导出的实体;

我目前的尝试:

  public static class IQueryableExtensions 
{
private static IMappingService mappingService;

//需要在应用程序初始化时调用
public static void InitialiseMapper(IMappingService service)
{
mappingService = service;
}

public static IEnumerable< TDto>映射< TAttribute,TDto>(这个IQueryable< TAttribute>值)
其中TDto:class
其中TAttribute:IEntity
{
返回mappingService.Map< TAttribute,TDto> );






因此,目前我的实现看起来像这样。

  var result = this.entityRepo 
.FindAll(a => a.Id = = someId)
.Take(1).Map< Entity,EntityDto>()
.FirstOrDefault();

问题:

1)如何从IQueryable对象推断实体类型2)我意识到我不能创建一个构造函数,它在创建静态时需要参数类。我是如何将映射器初始化为最佳/唯一的方式?

解决方案

我试图用反射。约束仅限于演示。如果您想多次调用反射代码,请务必缓存最终的方法信息。

  void Main()
{
var a = new Entity [] {new Entity {name =a},new Entity {name =b}};

Console.WriteLine(a.Take(1).Map< EntityDto>());
}

公共类实体
{
公共字符串名称;
}

public class EntityDto
{
public string dtoname;

}

public static class EntityExtensions
{
public static IEnumerable< U>映射< T,U>(这个IEnumerable< T> e)其中T:实体其中U:EntityDto,new()
{
foreach(var a in e)
{
yield返回新的U(){dtoname = a.name};
}
}


public static IEnumerable< U> Map< U>(此IEnumerable< object> e)
{
var method = typeof(EntityExtensions).GetMethods(BindingFlags.Static | BindingFlags.Public)
.Where(m => m.Name ==Map&& m.GetGenericArguments()。Length == 2)
.Single();
method = method.MakeGenericMethod(e.GetType()。GetGenericArguments()[0],typeof(U));

return method.Invoke(null,new object [] {e})as IEnumerable< U>;
}
}


Currently we implement a mapping service like this (the service uses automapper, and we make use of the projection feature on it for this part)

// Injected
// IGenericRepository<Entity> entityRepo

 var query = this.entityRepo
                 .FindAll(a => a.Id == someId)
                 .Take(1);

 var result = this.mappingService
                  .Map<Entity, EntityDto>(query)
                  .FirstOrDefault();

I'd like to create an extension that would allow me to do the following

var result = this.entityRepo
                 .FindAll(a => a.Id == someId)
                 .Take(1).Map<EntityDto>()   <--- Entity inferred from repo type
                 .FirstOrDefault();

My current attempt:

 public static class IQueryableExtensions
 {
     private static IMappingService mappingService;

     // will need to be called in app initialization
     public static void InitialiseMapper(IMappingService service)
     {
         mappingService = service;
     }

     public static IEnumerable<TDto> Map<TAttribute, TDto>(this IQueryable<TAttribute> value)
            where TDto : class
            where TAttribute : IEntity
     {
        return mappingService.Map<TAttribute, TDto>(value);
     }
 }

Thus currently my implementation would look like this.

var result = this.entityRepo
                     .FindAll(a => a.Id == someId)
                     .Take(1).Map<Entity,EntityDto>()
                     .FirstOrDefault();

Questions:

1) How would i go about inferring the entity type from the IQueryable object

2) I realize i cant create a constructor that takes parameters, when creating a static class. Is the way i init the mapper the best/only way?

解决方案

I tried that with reflection. The constraints are only for demo. If you want to call the reflection code multiple times be sure to cache the final methodinfo.

void Main()
{
    var a = new Entity[] {new Entity { name = "a"},new Entity { name = "b"}};

    Console.WriteLine(a.Take(1).Map<EntityDto>());
}

public class Entity
{
    public string name;
}

public class EntityDto
{
    public string dtoname;

}

public static class EntityExtensions
{
    public static IEnumerable<U> Map<T,U>(this IEnumerable<T> e) where T: Entity where U: EntityDto, new()
    {
        foreach(var a in e)
        {
            yield return new U() { dtoname = a.name };
        }
    }


    public static IEnumerable<U> Map<U>(this IEnumerable<object> e)
    {
        var method = typeof(EntityExtensions).GetMethods(BindingFlags.Static | BindingFlags.Public)     
        .Where(m => m.Name == "Map" && m.GetGenericArguments().Length == 2)
        .Single();
        method = method.MakeGenericMethod(e.GetType().GetGenericArguments()[0], typeof(U));

        return method.Invoke(null, new object[] { e}) as IEnumerable<U>;
    }
}

这篇关于仿制药&amp;静态类。实现查询帮助器方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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