Dav*_*nde 7 c# automapper automapper-2
我目前正在评估AutoMapper是否对我们的项目有益.我正在使用ASP.NET Web API开发RESTful Web API,我必须返回的一个内容是包含链接的资源.考虑这个简化的示例,使用以下域对象:
public class Customer
{
public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我需要将它映射到一个资源对象,有点像DTO,但增加了属性以方便REST.这是我的资源对象可能是这样的:
public class CustomerResource
{
public string Name { get; set; }
public Dictionary<string, string> Links { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
Links属性需要包含相关资源的链接.现在,我可以使用以下方法构建它们:
public IEnumerable<CustomerResource> Get()
{
Func<Customer, CustomerResource> map = customer =>
new CustomerResource
{
Name = customer.Name,
Links = new Dictionary<string, string>()
{
{"self", Url.Link("DefaultApi", new { controller = "Customers", name = customer.Name })}
}
}
var customers = Repository.GetAll();
return customers.Select(map);
}
Run Code Online (Sandbox Code Playgroud)
...但这非常繁琐,我有很多嵌套资源等等.我看到的问题是我无法使用AutoMapper,因为它不允许我提供投影期间需要某些事情,这些事情的范围限定为执行映射操作的点.在这种情况下,ApiController的Url属性提供了为我创建链接所需的UrlHelper实例,但可能还有其他情况.
你会如何解决这个难题?
PS我专门针对这个问题键入了这段代码,它在你的头脑中编译但在你喜欢的IDE中可能会失败.
我会考虑使用Custom Type Converter。类型转换器可以通过 IOC 容器注入上下文信息。或者,由于转换器是在配置时实例化的,因此它可以引用工厂,该工厂将在每次运行类型转换器时返回上下文信息。
简单的例子
您可以定义一个接口来获取当前的“上下文”(这意味着什么取决于您正在做什么以及如何实现事物,因此在这个示例中,我将仅使用当前的 HttpContext 来访问会话、服务器、项目、 ETC...):
public interface IContextFactory
{
HttpContext GetContext();
}
Run Code Online (Sandbox Code Playgroud)
实现很简单:
public class WebContextFactory : IContextFactory
{
public HttpContext GetContext()
{
return HttpContext.Current;
}
}
Run Code Online (Sandbox Code Playgroud)
您的自定义类型转换器可以从 IOC 容器获取 IContextFactory 的实例,并且每次运行映射时,您可以调用 GetContext() 来获取当前请求的上下文。
访问 URL 属性
UrlHelper 来自附加到当前控制器上下文的 Request 对象。不幸的是,这在 HttpContext 中不可用。但是,您可以重写 ApiController 上的 Initialize 方法并将controllerContext 存储在 HttpContext.Items 集合中:
protected override void Initialize(System.Web.Http.Controllers.HttpControllerContext controllerContext)
{
HttpContext.Current.Items["controllerContext"] = controllerContext;
base.Initialize(controllerContext);
}
Run Code Online (Sandbox Code Playgroud)
然后您可以从当前的 HttpContext 访问它:
var helper = ((HttpControllerContext) HttpContext.Current.Items["controllerContext"]).Request.GetUrlHelper();
Run Code Online (Sandbox Code Playgroud)
我不确定这是最好的解决方案,但它可以让您在自定义类型映射器中获得 UrlHelper 实例。
| 归档时间: |
|
| 查看次数: |
969 次 |
| 最近记录: |