wcf - Injecting dependencies into an IErrorHandler implementation -
i implementing ierrorhandler
in order centralize of error handling wcf service in 1 place. works well:
public class serviceerrorhandler : ierrorhandler { public bool handleerror(exception error) { // ..log.. } public void providefault(exception error, messageversion version, ref message fault) { // ..provide fault.. } }
now, we're using ninject inject dependencies in rest of service, , i'd same here. since wcf constructing objects based on configuration, , don't think have hooks process, need use property injection:
[inject] public iloggingservice logger { get; set; }
however, never seems injected. tried using ninject's mvc extensions set serviceerrorhandler
allow injection filter, didn't seem trick. there way make happen?
late answer, can inject dependencies ierrorhandler
creating custom servicehost
, let's testservicehost
.
in testservicehost
need do:
- implement constructor
ierrorhandler
parameter. - inside, create private nested class named
errorhandlerbehaviour
*, needs implement bothiservicebehavior
,ierrorhandler
. must have constructorierrorhandler
parameter. - override
onstarting()
method, adderrorhandlerbehaviour
service behaviours. behaviours must added beforebase.onstarting()
.
*the idea came juval lowy's example in book - "programming wcf services". more information faults , error extensions can find there.
here working host console application. don't use ioc there, pure di, can resolve logger ioc want:
using system; using system.collections.objectmodel; using system.servicemodel; using system.servicemodel.channels; using system.servicemodel.description; using system.servicemodel.dispatcher; namespace consolehost { class program { static void main(string[] args) { var logger = new dummylogger(); var errorhandler = new testerrorhandler(logger); servicehost host = new testservicehost(errorhandler, typeof(testservice), new uri("net.tcp://localhost:8002")); host.open(); console.writeline("press enter exit"); console.readkey(); } } [servicecontract] public interface itestservice { [operationcontract] string test(int input); } public class testservice : itestservice { public string test(int input) { throw new exception("test exception!"); } } public class testerrorhandler : ierrorhandler { private ilogger logger { get; } public testerrorhandler(ilogger logger) { logger = logger; } public bool handleerror(exception error) { logger.log(error.message); return true; } public void providefault(exception error, messageversion version, ref message fault) { faultexception fe = new faultexception(); messagefault message = fe.createmessagefault(); fault = message.createmessage(version, message, null); } } public class testservicehost : servicehost { private readonly ierrorhandler errorhandler; public testservicehost(ierrorhandler errorhandler, type servicetype, params uri[] baseaddresses) : base(servicetype, baseaddresses) { this.errorhandler = errorhandler; } protected override void onopening() { description.behaviors.add(new errorhandlerbehaviour(errorhandler)); base.onopening(); } class errorhandlerbehaviour : iservicebehavior, ierrorhandler { private readonly ierrorhandler errorhandler; public errorhandlerbehaviour(ierrorhandler errorhandler) { this.errorhandler = errorhandler; } bool ierrorhandler.handleerror(exception error) { return errorhandler.handleerror(error); } void ierrorhandler.providefault(exception error, messageversion version, ref message fault) { errorhandler.providefault(error, version, ref fault); } void iservicebehavior.applydispatchbehavior(servicedescription servicedescription, servicehostbase servicehostbase) { foreach (channeldispatcher channeldispatcher in servicehostbase.channeldispatchers) { channeldispatcher.errorhandlers.add(this); } } void iservicebehavior.addbindingparameters(servicedescription servicedescription, servicehostbase servicehostbase, collection<serviceendpoint> endpoints, bindingparametercollection bindingparameters) { } void iservicebehavior.validate(servicedescription servicedescription, servicehostbase servicehostbase) { } } } // dummy logger public interface ilogger { void log(string input); } public class dummylogger : ilogger { public void log(string input) => console.writeline(input); } }
and configuration:
<system.servicemodel> <services> <service name="consolehost.testservice"> <endpoint address="net.tcp://localhost:8002/testservice" binding="nettcpbinding" contract="consolehost.itestservice" /> </service> </services> </system.servicemodel>
btw. make sure added system.runtime.serialization
references
Comments
Post a Comment