i'm trying abstract/encapsulate following code client calls don't need repeat code. example, call, view model (mvvm) wcf service:
using (var channelfactory = new wcfchannelfactory<iprestoservice>(new nettcpbinding())) { var endpointaddress = configurationmanager.appsettings["prestoserviceaddress"]; iprestoservice prestoservice = channelfactory.createchannel(new endpointaddress(endpointaddress)); this.applications = new observablecollection<application>(prestoservice.getallapplications().tolist()); }
my original attempt @ refactoring this:
public static class prestowcf { public static iprestoservice prestoservice { { using (var channelfactory = new wcfchannelfactory<iprestoservice>(new nettcpbinding())) { var endpointaddress = configurationmanager.appsettings["prestoserviceaddress"]; return channelfactory.createchannel(new endpointaddress(endpointaddress)); } } } }
this allows view models make call 1 line of code now:
this.applications = new observablecollection<application>(prestowcf.prestoservice.getallapplications().tolist());
however, error the wcfchannelfactory
disposed. makes sense because disposed when view model tries use it. but, if removing using
, i'm not disposing of wcfchannelfactory
. note, wcfchannelfactory
embeds in wcfclientproxy
when createchannel()
called. why/how view model trying use after has been disposed.
how abstract code, keep view model calls simple possible, while disposing wcfchannelfactory
? hope explained enough.
edit - solved!
based on steaks answer, did it:
public static class prestowcf { public static t invoke<t>(func<iprestoservice, t> func) { using (var channelfactory = new wcfchannelfactory<iprestoservice>(new nettcpbinding())) { var endpointaddress = configurationmanager.appsettings["prestoserviceaddress"]; iprestoservice prestoservice = channelfactory.createchannel(new endpointaddress(endpointaddress)); return func(prestoservice); } } }
and here view model call:
this.applications = new observablecollection<application>(prestowcf.invoke(service => service.getallapplications()).tolist());
something following may
public static void useprestoservice(action<iprestoservice> callback) { using (var channelfactory = new wcfchannelfactory<iprestoservice>(new nettcpbinding())) { var endpointaddress = configurationmanager.appsettings["prestoserviceaddress"]; iprestoservice prestoservice = channelfactory.createchannel(new endpointaddress(endpointaddress)); //now have access service before channel factory disposed. don't have worry disposing channel factory. callback(prestoservice); } } useprestoservice(service => this.applications = new observablecollection<application>(service.getallapplications().tolist()));
side note:
i haven't used pattern disposables because haven't found of need disposables recently. however, in theory think pattern, taking callback executes inside of using block, when working disposables 2 reasons:
- it's simple
- it forces consumers of idisposables dispose of instances correctly...although agree (i think) c#'s team not raise compiler warnings when idisposables aren't disposed of in execution paths, it's still bit worrisome.
Comments
Post a Comment