我在服务层使用请求/响应模式。我有,例如:
public class FindPostsByTypeRequest : Request {
public PostType Type { get; set; }
}
public class FindPostsByTypeResponse : Response {
public IList<PostDto> Posts { get; set; }
public class PostDto {
public Int32 Id { get; set; }
public String Title { get; set; }
public String Text { get; set; }
}
}
要处理此请求,我有一个处理程序:
public class FindPostsByTypeHandler : Handler<FindPostsByTypeRequest, FindPostsByTypeResponse> {
private IContext _context;
public FindPostsByTypeHandler(IContext context) {
_context = context;
}
public FindPostsByTypeResponse Handle(FindPostsByTypeRequest request) {
IList<FindPostsByTypeRequest.PostDto> posts = _context.Posts
.Where(x => x.Type == request.Type)
.Select(x => new FindPostsByTypeRequest.PostDto {
Id = x.Id,
Title = x.Title,
Text = x.Text
}).ToList();
return new FindPostsByTypeResponse { Posts = posts };
}
}
然后我有一个调度员并按如下方式使用它:
FindPostsByTypeRequest request = new FindPostsByTypeRequest { Type = type };
FindPostsByTypeResponse response = _dispatcher.Send<FindPostsByTypeResponse>(request);
我正在尝试解决的问题:
当我按类型查找帖子有时我需要标签...有时候我不需要。 当然,我总是可以将标签放入我的DTO并使用或不使用... 但是应该避免装载我不需要的东西......
所以基本上我需要按类型获取帖子并“告诉”处理程序我需要什么数据。
我的想法是这样的:
_dispatcher.Send<FindPostsByTypeResponse<PostWithTagsModel>>(request);
PostWithTagsModel将是我需要的DTO。然后在我的处理程序中我会:
public class FindPostsByTypeHandler : Handler<FindPostsByTypeRequest, FindPostsByTypeResponse> {
private IContext _context;
public FindPostsByTypeHandler(IContext context) {
_context = context;
}
public FindPostsByTypeResponse<PostsByType> Handle(FindPostsByTypeRequest request) {
IList<FindPostsByTypeResponse.PostDto> posts = _context.Posts
.Where(x => x.Type == request.Type)
.Select(x => new FindPostsByTypeResponse.PostDto {
Id = x.Id,
Title = x.Title,
Text = x.Text
}).ToList();
return new FindPostsByTypeResponse { Posts = posts };
}
public FindPostsByTypeResponse<PostsWithoutTagsDto> Handle(FindPostsByTypeRequest request) {
IList<FindPostsByTypeResponse.PostsWithoutTagsDto> posts = _context.Posts
.Where(x => x.Type == request.Type)
.Select(x => new FindPostsByTypeResponse.PostsWithoutTagsDto {
Id = x.Id,
Title = x.Title,
Text = x.Text
}).ToList();
return new FindPostsByTypeResponse { Posts = posts };
}
public FindPostsByTypeResponse<PostsWithTagsDto> Handle(FindPostsByTypeRequest request) {
// Remaining code
}
}
我不确定这是可能的,甚至是最好的方法......
基本上我需要“告诉”处理程序我需要哪种格式的响应中包含的DTO。
我怎么能或应该这样做?
答案 0 :(得分:-1)
更新:
好的,如果不确切知道你的其他课程是什么样的,这里有一个近似的例子,我认为包含所有辅助课程对你有用。我把它放在Visual Studio中并确认它编译。在此方法中,ResponseTypeEnum子类实例根据可通过子类的枚举类上的ConstructItem方法的类型映射来确定要实例化的帖子类型。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestRequestResponse
{
#region Generic portions
/// <summary>
/// Base request class
/// </summary>
public class Request {}
/// <summary>
/// Base response class
/// </summary>
public class Response {}
/// <summary>
/// Generic typed namespace for Response/Request support
/// </summary>
/// <typeparam name="tRequestResponseSet">Request/Response set type parameter (for namespace constraining)</typeparam>
/// <typeparam name="tItem">Item type parameter</typeparam>
/// <typeparam name="tSourceItem">Source item type parameter</typeparam>
public class RequestResponseSet<tRequestResponseSet, tItem, tSourceItem>
where tRequestResponseSet : RequestResponseSet<tRequestResponseSet, tItem, tSourceItem>
where tItem : RequestResponseSet<tRequestResponseSet, tItem, tSourceItem>.Item
{
/// <summary>
/// Base item class
/// </summary>
public
abstract class Item
{
public
abstract void Initialize(tSourceItem sourceItem);
}
/// <summary>
/// Base type specific subclassable enum class (see https://github.com/TyreeJackson/atomic/blob/master/Atomic.Net/DataTypes/SubclassableEnum.cs for a more generic version)
/// </summary>
public
abstract class ResponseTypeEnum
{
private
static Dictionary
<
string,
ResponseTypeEnum
> allValues = new Dictionary<string,ResponseTypeEnum>();
private string type;
private Func<tItem> constructItem;
protected ResponseTypeEnum
(
string type,
Func<tItem> constructItem
)
{
this.type = type;
this.constructItem = constructItem;
}
public tItem ConstructItem(tSourceItem sourceItem)
{
var returnItem = this.constructItem();
returnItem.Initialize(sourceItem);
return returnItem;
}
public
static ResponseTypeEnum Select(string type)
{
ResponseTypeEnum returnTypeEnum = null;
return type == null || !ResponseTypeEnum.allValues.TryGetValue(type, out returnTypeEnum)
? null
: returnTypeEnum;
}
public
static
implicit
operator ResponseTypeEnum(string type)
{
return ResponseTypeEnum.Select(type);
}
public
static
implicit
operator string(ResponseTypeEnum typeEnum)
{
return typeEnum == null ? null : typeEnum.type;
}
}
}
#endregion Generic portions
#region Post specific portions
/// <summary>
/// Stored post /entity
/// </summary>
public class StoredPost
{
public String Type { get; set; }
public Int32 Id { get; set; }
public String Title { get; set; }
public String Text { get; set; }
public List<String> Tags { get; set; }
}
/// <summary>
/// Post specific typed namespace
/// </summary>
public class PostsSet : RequestResponseSet<PostsSet, PostsSet.Post, StoredPost>
{
public class Types : ResponseTypeEnum
{
public static Types Basic = new Types("basic", ()=>new Post());
public static Types WithTags = new Types("withTags", ()=>new PostWithTags());
protected Types(string type, Func<Post> createPost) : base(type, createPost) {}
}
public class Post : Item
{
public Int32 Id { get; set; }
public String Title { get; set; }
public String Text { get; set; }
public
override void Initialize(StoredPost sourceItem)
{
this.Id = sourceItem.Id;
this.Title = sourceItem.Title;
this.Text = sourceItem.Text;
}
}
public class PostWithTags : Post
{
public List<String> Tags { get; set; }
public
override void Initialize(StoredPost sourceItem)
{
base.Initialize(sourceItem);
this.Tags = sourceItem.Tags;
}
}
}
/// <summary>
/// Post specific response class
/// </summary>
public class FindPostsResponse : Response
{
public IList<PostsSet.Post> Posts { get; set; }
}
/// <summary>
/// Post specific request class
/// </summary>
public class FindPostsRequest : Request
{
public string Type { get; set; }
}
/// <summary>
/// Post specific context
/// </summary>
public interface IContext
{
IEnumerable<StoredPost> Posts { get; set; }
}
/// <summary>
/// Post specific handler
/// </summary>
public class FindPostHandler
{
private IContext context;
public FindPostHandler(IContext context)
{
this.context = context;
}
public FindPostsResponse Handle(FindPostsRequest request)
{
var type = PostsSet.Types.Select(request.Type);
return
type == null
? null
: new FindPostsResponse()
{
Posts =
this.context.Posts
.Where(x => x.Type == request.Type)
.Select(x => type.ConstructItem(x))
.ToList()
};
}
}
#endregion Post specific portions
}