In developing a WPF application that allows editing of article and carrier (pallet, racking) data (in a CRUD-fashion) I'm looking how to manage the lifecycle of the WCF clients connecting to the service that contains the actual data.
I prefer to use an MVVM approach using Caliburn Micro and StructureMap or Castle Windsor.
My main issue is not the creation of WCF client channels or factories, but more important the cleanup after use. I intend to use per-request lifecycle on the server side, as such I will need to create and dispose my clients on a per-request basis. As such I have the following in mind:
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);
}
}
}
As noted in the comment this won't work because IArticleCrud is not IDisposable. IArticleCrud is used to create a ChannelFactory on the client side to generate proxies for the service implementing the same interface. I'd happily swap out this code for the following:
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);
}
}
However, this doesn't solve my problem as I'm still not dealing with the disposal of the WCF client. I could however make the IMediator create a new nested container on the Send action and have it disposed after the Send action completes, but it seems like a lot of hassle.
Am I getting it all wrong, or does it just require a lot of effort just to perform a WCF call from a WPF application?
As a sidenote, I will be having more services than just these few CRUD services, so the perhaps pragmatic solution of fixing this in my CRUD services is not an option.