【发布时间】:2016-03-01 13:45:48
【问题描述】:
在开发允许编辑物品和载体(托盘、货架)数据(以 CRUD 方式)的 WPF 应用程序时,我正在研究如何管理连接到包含实际数据的服务的 WCF 客户端的生命周期.
我更喜欢使用 Caliburn Micro 和 StructureMap 或 Castle Windsor 的 MVVM 方法。
我的主要问题不是创建 WCF 客户端通道或工厂,而是更重要的是使用后的清理。我打算在服务器端使用每个请求的生命周期,因此我需要在每个请求的基础上创建和处置我的客户端。因此,我有以下想法:
public class Article
{
public int Id { get; set; }
public string ArticleId { get; set; }
}
[ServiceContract]
public interface IArticleCrud
{
[OperationContract]
Article CreateArticle(string articleId);
[OperationContract]
void Delete(int articleId);
}
public class ArticlesViewModel
{
private readonly Func<IArticleCrud> articleCrudFactory;
public ArticlesViewModel(Func<IArticleCrud> articleCrudFactory)
{
this.articleCrudFactory = articleCrudFactory;
}
public void Delete(int articleId)
{
// Doesn't work since IArticleCrud is not IDisposable
using (var crud = articleCrudFactory())
{
crud.Delete(articleId);
}
}
}
正如评论中所述,这不起作用,因为 IArticleCrud 不是 IDisposable。 IArticleCrud 用于在客户端创建一个 ChannelFactory 来为实现相同接口的服务生成代理。我很乐意将这段代码换成以下代码:
public class DeleteArticleCommand : IRequest
{
public int Id { get; set; }
}
public class ArticlesViewModel
{
private readonly IMediator mediator;
public ArticlesViewModel(IMediator mediator)
{
this.mediator = mediator;
}
public void Delete(int articleId)
{
mediator.Send(new DeleteArticleCommand {Id = articleId});
}
}
public class DeleteArticleCommandHandler : RequestHandler<DeleteArticleCommand>
{
private readonly IArticleCrud articleCrud;
public DeleteArticleCommandHandler(IArticleCrud articleCrud)
{
this.articleCrud = articleCrud;
}
protected override void HandleCore(DeleteArticleCommand message)
{
articleCrud.Delete(message.Id);
}
}
但是,这并不能解决我的问题,因为我还没有处理 WCF 客户端的处置问题。但是,我可以让 IMediator 在 Send 操作上创建一个新的嵌套容器,并在 Send 操作完成后将其处理掉,但这似乎很麻烦。
我是不是全都搞错了,还是仅仅为了从 WPF 应用程序执行 WCF 调用就需要付出很多努力?
作为旁注,我将拥有比这几个 CRUD 服务更多的服务,因此在我的 CRUD 服务中修复此问题的实用解决方案可能不是一种选择。
【问题讨论】:
-
这个问题是关于 WCF 会话生命周期的吗?
-
不,我想通过会话 PerRequest 使 WCF 层尽可能薄。
标签: c# wpf wcf mvvm dependency-injection