c# - Implement extensibility on callback? -
currently, working on api, , developers can subscribe know updates.
so right implementing interface iresult
, can send different parameters in callback result. problem right if in future, want add new callback, have add argument in method, , developers need change method call. there solution this?
public interface iresult { int { get; set; } } public class concreteresult : iresult { public int { get;set; } } public class myapi { public delegate void myapidelegate(iresult result); public void startservice(myapidelegate callback, myapidelegate callback2) { //step 1 int = 0; concreteresult result1 = new concreteresult(); result1.i = i; callback(result1); //step 2 += 1; concreteresult result2 = new concreteresult(); result2.i = i; callback2(result2); //potentially added in future //i += 1; //callback3(); } public void main() { //developers use api startservice(developercallback, developercallback2); } private void developercallback(iresult result) { console.writeline(result.i); } private void developercallback2(iresult result) { console.writeline(result.i); } }
oddly recommending events, nobody showing example. i'll bite.
judging naming conventions i'm guessing come java land. (c# methods pascalcase). c# has events, make things simpler. recommend study them up, they're quite common in c# code.
all have define public event on class, , have class invoke event necessary. (do ?.
because unsubscribed event weirdly null).
then consuming class, subscribe handlers using +=
.
this allows add new events in future without consumers having worry it.
public class myapi { public event action<iresult> callback1; public event action<iresult> callback2; public void startservice() { //step 1 int = 0; concreteresult result1 = new concreteresult(); result1.i = i; callback1?.invoke(result1); //step 2 += 1; concreteresult result2 = new concreteresult(); result2.i = i; callback2?.invoke(result2); //potentially added in future //i += 1; //callback3(); } } public static class program { public static void main() { //developers use api var api = new myapi(); api.callback1 += developercallback; api.callback2 += developercallback2; api.startservice(); } private static void developercallback(iresult result) { console.writeline(result.i); } private static void developercallback2(iresult result) { console.writeline(result.i); } }
also simple event handlers, can subscribe inline:
api.callback1 += result => { console.writeline(result.i); };
or simpler one-liners:
api.callback1 += result => console.writeline(result.i);
since asked, option bit more heavier simple events, more powerful reactive extensions. if want use these, can write code this:
using system.reactive.subjects; public class myapi { private readonly subject<iresult> callback1 = new subject<iresult>(); private readonly subject<iresult> callback2 = new subject<iresult>(); public void startservice() { //step 1 int = 0; concreteresult result1 = new concreteresult(); result1.i = i; callback1.onnext(result1); //step 2 += 1; concreteresult result2 = new concreteresult(); result2.i = i; callback2.onnext(result2); } public iobservable<iresult> callback1 => this.callback1; public iobservable<iresult> callback2 => this.callback2; } public static class program { public static void main() { var api = new myapi(); // subscribing returns disposable subscription, , disposing unsubscribes. // means can use lambda syntax , still unsubscribe later idisposable subscription = api.callback1.subscribe(result => console.writeline(result.i)); api.startservice(); // writes result. // once disposed, event no longer called subscription.dispose(); api.startservice(); // doesn't write result. // since idisposable special thing can scoped using blocks in c#, can following: using (api.callback1.subscribe(result => console.writeline(result.i))) { api.startservice(); // writes result } api.startservice(); // doesn't write result } }
Comments
Post a Comment