I have this code:
abstract class CommunicationChannel<Client> : IDisposable where Client : class, IDisposable {
protected Client client;
public void Open() {
try
{
client = CreateClient();
}
catch (Exception)
{
client.Dispose();
throw;
}
}
public virtual void Dispose() {
client.Dispose();
}
private Client CreateClient()
{
return Activator.CreateInstance<Client>();
}
}
class Communicator : CommunicationChannel<Client>
{
// here I have specific methods
void Method1(args) {
Open();
try {
client.Method1(args);
}
catch(Exception) {
// Cleanup
}
}
// this is getting too verbose already
void Method2(args) {
Open();
try {
client.Method2(args);
}
catch(Exception) {
// Cleanup
}
}
}
class Client: IDisposable {
public void Dispose()
{
}
}
I would want in the base class CommunicationChannel to be able to intercept somehow all the calls related to client and handle the exceptions before propagating them to the derived class CommunicationChannel. The generic parameter of the base class can contain different methods (in my example we only have Method 1)
I would ideally want a solution in which I don't have to call CommunicationChannel.CallMethod("Method1", args).
You could make client private and force subclasses to access it in a Func or Action. You can then add you before/after logic:
abstract class CommunicationChannel<Client> : IDisposable where Client : class, IDisposable
{
private Client client;
protected TResult WithClient<TResult>(Func<Client, TResult> f)
{
this.Open();
try
{
return f(client);
}
catch (Exception)
{
//cleanup
}
return default(TResult);
}
protected void WithClient(Action<Client> act)
{
WithClient<object>(c => { act(c); return null; })
}
}
your subclasses can then do:
class Communicator : CommunicationChannel<Client>
{
bool Method1(args)
{
return WithClient<bool>(c => { return c.Method1(args); });
}
}
I think this is a good case to use AOP (Aspect Oriented Programming).
What you could do is set up an aspect which OnEntry, executes the Open method and catches the exceptions with the OnException method.
Then all you have to do is decorate the methods you want to use that aspect on with an Attribute
Ill demonstrate what i mean using PostSharp:
public class CommunicationAspect : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
var communicationObject = args.Instance as CommunicationObject;
communicationObject.Open();
args.FlowBehavior = FlowBehavior.Continue;
}
public override void OnException(MethodExecutionArgs args)
{
_logger.log(string.Format("Exception {0} has occured on method {1}", args.Exception, args.Method.Name));
}
}
Then, decorate your methods with this attribute:
class Communicator : CommunicationChannel<Client>
{
[CommunicationAspect]
void Method1(args)
{
client.Method1(args);
}
[CommunicationAspect]
void Method2(args)
{
client.Method2(args);
}
}
PostSharp is a great framework that makes it really easy to get started, I suggest you look into it.
Related
I have a number of methods that are called on different 3rd party systems. I now have another 3rd party system that will have the same set of methods actioned against it. If both 3rd party systems are connected I will then call the methods on each object in turn.
Currently I have a class that I pass round that I can call the method once and it checks and then calls it on each system that is enabled, this has an instance of each objects classes, similar to this:
public class AACSCaller
{
3rdPartySystem1 _system1;
3rdPartySystem2 _system2;
public AACSCaller(Settings appSettings)
{
_appSettings = appSettings;
if (appSettings.system1Enabled)
{
_system1 = new 3rdPartySystem1();
}
if (appSettings.system2Enabled)
{
_system2 = new 3rdPartySystem2();
}
}
public void Method1()
{
if (appSettings.system1Enabled)
{
_system1.Method1();
}
if (appSettings.system2Enabled)
{
_system2.Method1();
}
}
public void Method2()
{
if (appSettings.system1Enabled)
{
_system1.Method2();
}
if (appSettings.system2Enabled)
{
_system2.Method2();
}
}
}
Is this sensible, as it does seem there maybe a better way and I may well be connecting additional system at some point.
A possible solution here is to define an interface or base class for 3rdPartySystem1 and 3rdPartySystem2 classes, store instances in a collection and call required methods for every item in collection. If only one system is enabled, you'll have only one item in collection, if both is enabled, you'll call them one by one in loop
public interface IThirdPartySystem
{
void Method1();
void Method2();
}
public class ThirdPartySystem1 : IThirdPartySystem
{
//implementation
}
public class ThirdPartySystem2 : IThirdPartySystem
{
//implementation
}
public class AACSCaller
{
IList<IThirdPartySystem> _systems = new List<IThirdPartySystem>();
public AACSCaller(Settings appSettings)
{
_appSettings = appSettings;
if (appSettings.system1Enabled)
{
_systems.Add(new ThirdPartySystem1());
}
if (appSettings.system2Enabled)
{
_systems.Add(new ThirdPartySystem2());
}
}
public void Method1()
{
foreach (var system in _systems)
system.Method1();
}
public void Method2()
{
foreach (var system in _systems)
system.Method2();
}
}
I suggest you to use interface that have Method1 and Method2 methods and then create to classes System1 and System2 that are implements the interface. Where AACSCaller is create you initialize the correct implementation of the interface and in your methods your just Call to the correct instance method without conditions.
public class AACSCaller
{
IThirdPartySystem ThirdPartySystem;
public AACSCaller(Settings appSettings)
{
_appSettings = appSettings;
ThirdPartySystem = appSettings.system1Enabled ? new ThirdPartySystem1() : new ThirdPartySystem2();
}
public void Method1() => ThirdPartySystem.Method1();
public void Method2() => ThirdPartySystem.Method2();
}
public interface IThirdPartySystem
{
void Method1();
void Method2();
}
public class ThirdPartySystem1 : IThirdPartySystem
{
public void Method1()
{
//code here..
}
public void Method2()
{
//code here..
}
}
public class ThirdPartySystem2 : IThirdPartySystem
{
public void Method1()
{
//code here..
}
public void Method2()
{
//code here..
}
}
I'm building an API (for a game-engine) which exposes two interfaces called IWindow and IEngineWindow.
The IWindow interface is supposed to be implemented by an API-user and the IEngineWindow interface is used by the engine to interact with the window.
The window object should have a private member of the type List<IWindowControl>.
I could use an abstract class and get rid of the interfaces but then i would have implementation-details in my API which i don't want.
My theoretical solution to the problem is that the API-user implements IWindow in his own class and calls a method (something like GetEngineWindow(typeof(MyWindowClass))) which returns an object which is identical to an instance of MyWindowClass except that it also implements the IEngineWindow interface.
I was planning to use System.Reflection.Emit in the GetEngineWindow() method to dynamically combine MyWindowClass with an internal class which implements the IEngineWindow interface but i quickly realised that this would be a mayor project of it's own.
My question boils down to if there is a simpler solution to remove this kind of implementation-details from an API or if there exists a library (free for commercial use) to do this kind of class-fusing.
In case my question is too abstract, here is a code example of what i want to be able to do:
//API (dll-file)
interface IWindow
{
void BeforeClose();
}
interface IEngineWindow
{
void Show();
}
//Built into engine (written by me)
class Program
{
static void Main(string[] args)
{
object window = CombineClasses(typeof(Testwindow), typeof(EngineWindow));
((IWindow)window).BeforeClose(); //Outputs: Closing...
((IEngineWindow)window).Show(); //Outputs: Showing window...
}
}
class EngineWindow : IEngineWindow
{
public void Show()
{
Console.WriteLine("Showing window...");
}
}
//External assembly (dll-file)
class Testwindow : IWindow
{
public void BeforeClose()
{
Console.WriteLine("Closing...");
}
}
This sounds like you need a wrapper.
Let your internal class take an IWindow instance in its constructor
store it in a private field
implement both interfaces
and forward all IWindow members to the internal instance
Update: if you consider CastleWindsor a simpler approach, here it is (using xUnit for tests):
namespace Mixins
{
using System;
using Castle.DynamicProxy;
using Xunit;
public interface IA
{
void Do();
}
public interface IB
{
void Something();
}
public class A : IA
{
public void Do()
{
throw new NotImplementedException("A");
}
}
public class B : IB
{
public void Something()
{
throw new NotImplementedException("B");
}
}
public class Blender
{
[Fact]
public void Mix()
{
var options = new ProxyGenerationOptions();
// the instances for A and B would be the user provided and yours
options.AddMixinInstance(new A());
options.AddMixinInstance(new B());
var proxy = new ProxyGenerator().CreateClassProxy<object>(options);
Assert.IsAssignableFrom<IA>(proxy);
Assert.IsAssignableFrom<IB>(proxy);
try
{
((IA)proxy).Do();
}
catch (NotImplementedException ex)
{
if (ex.Message != "A")
{
throw;
}
}
try
{
((IB)proxy).Something();
}
catch (NotImplementedException ex)
{
if (ex.Message != "B")
{
throw;
}
}
}
}
}
I am the author of NCop - A composite-aspect framework that can help you achieve your goal.
NCop wiki
You basically need to create a new composite type interface that will implement both of your window interfaces and mark it as a composite using the TransientComposite attribute.
[TransientComposite]
public interface ICompositeWindow : IWindow, IEngineWindow
{
}
Order NCop to match between interfaces and implementations using Mixins attribute.
[TransientComposite]
[Mixins(typeof(EngineWindow), typeof(Testwindow))]
public interface ICompositeWindow : IWindow, IEngineWindow
{
}
create a CompositeContainer that will emit the new type.
class Program
{
static void Main(string[] args) {
ICompositeWindow window = null;
var container = new CompositeContainer();
container.Configure();
window = container.Resolve<ICompositeWindow>();
window.Show();
window.BeforeClose();
}
}
your final code should be:
using System;
using NCop.Composite.Framework;
using NCop.Mixins.Framework;
using NCop.Composite.Runtime;
namespace NCop.Samples
{
[TransientComposite]
[Mixins(typeof(EngineWindow), typeof(Testwindow))]
public interface ICompositeWindow : IWindow, IEngineWindow
{
}
public interface IWindow
{
void BeforeClose();
}
public interface IEngineWindow
{
void Show();
}
public class EngineWindow : IEngineWindow
{
public void Show() {
Console.WriteLine("Showing window...");
}
}
public class Testwindow : IWindow
{
public void BeforeClose() {
Console.WriteLine("Closing...");
}
}
class Program
{
static void Main(string[] args) {
ICompositeWindow window = null;
var container = new CompositeContainer();
container.Configure();
window = container.Resolve<ICompositeWindow>();
window.Show();
window.BeforeClose();
}
}
}
I was wondering how to catch an exception from a constructor in a derived class with C#. Something as such:
public class MyClassA
{
public MyClassA()
{
//Do the work
if (failed)
{
throw new Exception("My exception");
}
}
}
public class MyClassB : MyClassA
{
public MyClassB()
{
//How to catch exception from a constructor in MyClassA?
}
}
Do not even try to figure out how to do this. If the base class constructor is throwing an exception, it means the base class is in a bad state. If the base class is in a bad state, it means the derived class is in a bad state. The point of a constructor is to get an object into a useable state. It failed. Get out!
i would handle it like this i think
public class MyClassA
{
protected bool test;
public MyClassA()
{
//Do the work
if (true)
{
test = true;
return;
}
}
}
public class MyClassB : MyClassA
{
public MyClassB()
{
if (base.test)
{
//How to catch exception from a constructor in MyClassA?
}
}
}
1) A workaround: create a factory method in the derived:
class MyClassB : MyClassA
{
public static MyClassB Create()
{
try
{
return new MyClassB();
}
catch
{
// try to handle
}
}
}
2) or create a similar in the base and don't throw in the constructor but in the method instead:
class MyClassA
{
public static MyClassA Create()
{
MyClassA x = new MyClassA();
if (x.Failed)
throw new Exception();
return x;
}
}
3) or provide an overridable strategy to handle failed state:
class MyClassA
{
public MyClassA
{
if (failed)
OnFail();
}
protected virtual void OnFail()
{
throw new Exception();
}
}
class MyClassB : MyClassA
{
protected override void OnFail()
{
// don't throw
}
}
I solve the same problem with static method:
public class PdfReaderExtended : PdfReader
{
public PdfReaderExtended(string filename) : base(filename)
{
}
public static PdfReaderExtended CreateInstance(string filename)
{
var name = Path.GetFileName(filename);
try
{
return new PdfReaderExtended(filename);
}
catch (Exception ex)
{
throw new ClientException("Oops");
}
}
}
Problem:
I would like to catch any exceptions from any method in a class so that I may record class specific data to the exception for logging before it is passed up the stack. I know that I can put a try-catch in every method of the class, but there are many methods and It seems there should be a more efficient way.
Example of what I am currently doing:
public class ClassA
{
private int x;
private int y;
public void Method1()
{
try
{
//Some code
}
catch(Exception ex)
{
ex.Data.Add("x", x);
ex.Data.Add("y", y);
throw;
}
}
public void Method2()
{
try
{
//Some code
}
catch (Exception ex)
{
ex.Data.Add("x", x);
ex.Data.Add("y", y);
throw;
}
}
}
Example of what I would like to do:
public class ClassB : IUnhandledErrorHandler
{
private int x;
private int y;
public void Method1()
{
//Some code
}
public void Method2()
{
//Some code
}
void IUnhandledErrorHandler.OnError(Exception ex)
{
ex.Data.Add("x", x);
ex.Data.Add("y", y);
throw;
}
}
public interface IUnhandledErrorHandler
{
void OnError(Exception ex);
}
Note:
This class is a service in a WCF project and implements a ServiceContract. I have tried adding an ErrorHandler to the service's ChannelDispatcher. However, when the error reaches the ErrorHandler it is already beyond the scope of the class where the error occurred, so I cannot access the class details.
Solution:
public class ClassC
{
public ClassC()
{
AppDomain.CurrentDomain.FirstChanceException += OnError;
}
private int x;
private int y;
public void Method1()
{
//Some code
}
public void Method2()
{
//Some code
}
private void OnError(object sender, System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs e)
{
e.Exception.Data["x"] = x;
e.Exception.Data["y"] = y;
}
}
If you run on .NET 4, you might use the FirstChanceException event from the AppDomain.
You can accomplish this by inheriting from System.ContextBoundObject. It's not as pretty as you would hope, and I believe there probably is some significant overhead associated with it, but as far as I know it's the only way to do what you describe.
As requested here is further elaboration...as mentioned it ain't pretty, but here is a minimal implementation needed to make this work. The main method of interest is the AOPSink.SyncProcessMessage method. It is called prior to any method on a 'Test' object, and the call to NextSink.SyncProcessMessage(msg) is what actually invokes the originally called method. You can inspect (and modify) which method was called and the parameters passed by playing with the IMessage parameter passed to SyncProcessMessage, and you can inspect/modify the return value (or thrown Exception) by playing with the IMessage returned from NextSink.SyncProcessMessage. There is significant performance overhead for this functionality, so I wouldn't recommend it for high traffic objects outside of debugging purposes.
[AOP]
class Test : ContextBoundObject
{
public void TestMethod()
{
throw new Exception();
}
}
[AttributeUsage(AttributeTargets.Class)]
public class AOPAttribute : ContextAttribute
{
public AOPAttribute() : base("AOPAttribute") { }
public override void GetPropertiesForNewContext(IConstructionCallMessage ctor)
{
ctor.ContextProperties.Add(new AOPProperty());
}
public override bool IsContextOK(Context ctx, IConstructionCallMessage ctorMsg)
{
return false;
}
}
public class AOPProperty : IContextProperty, IContributeServerContextSink
{
public IMessageSink GetServerContextSink(IMessageSink nextSink)
{
return new AOPSink(nextSink);
}
public string Name { get { return "AOP"; } }
public bool IsNewContextOK(Context ctx) { return true; }
public void Freeze(Context ctx) { }
}
public class AOPSink : IMessageSink
{
public AOPSink(IMessageSink nextSink) { this.NextSink = nextSink; }
public IMessageSink NextSink { get; private set; }
public IMessage SyncProcessMessage(IMessage msg)
{
// inspect method+params by playing with 'msg' here
IMessage m = NextSink.SyncProcessMessage(msg);
// inspect returnval/exception by playing with 'm' here
return m;
}
public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
{
throw new NotSupportedException();
}
}
Suppose you had such code:
public Base
{
abstract void Register();
}
public Registrator1: Base
{
override void Register()
{
//uses the current state of the object to populate the UI captions
}
}
public Registrator2: Base
{
override void Register()
{
//uses the current state of the object to populate the UI captions
}
}
But When you receive a new business rule asking you to write Registrator3 which actually registers based on some parameter and you change your code base to the next:
public Base
{
abstract void Register(externalParam);
}
public Registrator1: Base
{
override void Register(externalParam)
{
//uses the current state of the object to populate theUI
}
}
public Registrator2: Base
{
override void Register(externalParam)
{
//uses the current state of the object to populate the UI
}
}
public Registrator3: Base
{
override void Register(externalParam)
{
//uses a DDD - service passed in the params to populate the UI
}
}
But Registrator1 and Registrator2 do not need that param and the code becomes smelly. What are the ways to re-write this code?
You could use an object as a parameter here; which is commonly used in scenarios where the number of parameters can vary depending on the call being used.
struct RegistrationInfo
{
public static readonly RegistrationInfo Empty = new RegistrationInfo();
public string Username;
public string CustomerName;
public string Validity;
}
abstract class Base
{
public abstract void Register(RegistrationInfo info);
// If you want to retain the paramaterless call:
public void Register()
{
Register(RegistrationInfo.Empty);
}
}
class Registrar1 : Base
{
public override void Register(RegistrationInfo info)
{
if (info.Username == null) throw new ArgumentNullException("info.Username");
}
}
class Registrar2 : Base
{
public override void Register(RegistrationInfo info)
{
if (info.CustomerName == null) throw new ArgumentNullException("info.CustomerName");
}
}
This has the advantage that you don't need to change method parameters (which is breaking interface) each time a parameter is added. The usage also becomes somewhat self-documenting:
var r = new Registrar1();
r.Register(new RegistrationInfo(){ Username = "JimJoe" });
r.Register(RegistrationInfo.Empty);
It's like air freshener for this type of code smell, while it's still smelly; you can make it smell nicer.
Finally you can make the call-site cleaner by making it a params argument (this has a small amount of overhead); in all honesty though it is more smelly because it's a language hack. Finally you could improve it with generics:
class RegistrationInfo
{
}
class RegistrationInfo1 : RegistrationInfo
{
public string Arg;
}
class RegistrationInfo2 : RegistrationInfo
{
public int Arg;
}
interface IBase<in TRegistration>
where TRegistration : RegistrationInfo
{
void Register(TRegistration registration);
}
class Base : IBase<RegistrationInfo>
{
public void Register(RegistrationInfo registration)
{
}
}
class Registrar1 : IBase<RegistrationInfo1>
{
public void Register(RegistrationInfo1 arg)
{
}
}
class Registrar2 : IBase<RegistrationInfo2>
{
public void Register(RegistrationInfo2 arg)
{
}
}
Is it not possible to contain the logic for externalParam in Registrator3?
In other words, Registrator3 uses the param, then calls the unmodified parameterless base?
A lot really depends on where the logic belongs. If it is something intrinsic to the base, then put it in the base, and either overload the Register() function or supply a default value for the param so that sub classes don't need to provide it.
Assuming you want to reuse the registration logic from the base class, you could update the code as follows:
public class Base
{
public virtual void Register(object externalParam)
{
// base registration logic goes here
}
}
public class Registrator1: Base
{
public override void Register(object externalParam)
{
base.Register(null);
// custom registration logic goes here
}
}
public class Registrator2: Base
{
public override void Register(object externalParam)
{
base.Register(null);
// custom registration logic goes here
}
}
public class Registrator3: Base
{
public override void Register(object externalParam)
{
base.Register(externalParam);
// custom registration logic goes here
}
}
HTH,
Cosmin
EDIT: Updated code to compile.