Return exception from proxy - c#

I'm using the heavily-undocumented Castle dynamic-proxy system. I've managed to make it do almost everything I want, except for one thing: How do you make a proxied method throw an exception instead of returning a value?
public sealed class MyInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
if (CheckArgs(invocation.Arguments))
{
invocation.ReturnValue = DoRealWork(invocation.Arguments);
}
else
{
invocation.Exception = new InvalidOperationException(); // How?
}
}
}

From the point of view of the proxied object the interceptor is not visible; it simply calls its own virtual method, and DynamicProxy invokes the correct interceptor methods before returning the ReturnValue to the caller.
So if you want to throw an exception just throw it from the interceptor:
if (CheckArgs(invocation.Arguments))
{
invocation.ReturnValue = DoRealWork(invocation.Arguments);
}
else
{
throw new InvalidOperationException();
}
From the point of view of the caller it will be an exception in the called method.
Edit for comment:
Regarding the type of the exception thrown in the generator I have the correct type, not a wrapper:
public interface IDummy
{
string DoSomething();
}
public class Dummy: IDummy {
public virtual string DoSomething()
{
return string.Empty;
}
}
public class MyCustomException : Exception {}
public class CustomIntercept: IInterceptor
{
public void Intercept(IInvocation invocation)
{
throw new MyCustomException();
}
}
internal class Program
{
private static void Main(string[] args)
{
var pg = new ProxyGenerator();
GetValue(pg.CreateInterfaceProxyWithoutTarget<IDummy>(new CustomIntercept()));
GetValue(pg.CreateClassProxy<Dummy>(new CustomIntercept()));
GetValue(pg.CreateClassProxyWithTarget<Dummy>(new Dummy(), new CustomIntercept()));
GetValue(pg.CreateInterfaceProxyWithTarget<IDummy>(new Dummy(), new CustomIntercept()));
}
private static void GetValue(IDummy dummy)
{
try
{
dummy.DoSomething();
}
catch (Exception e)
{
Console.WriteLine(e.GetType().Name);
}
}
}
All four outputs are MyCustomException
Can you make sure that the TargetInvocationException doesn't come from your own code? What version of the DynamicProxy are you using (I'm using the one in Castle.Core 3.2)

Related

Autofac method level interception with Castle DynamicProxy in .NET Core 2

I currently wrote an Interceptor which code is below
public class TransactionalInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
using (var transaction = ...)
{
try
{
invocation.Proceed();
transaction.Commit();
}
catch
{
transaction.Rollback();
}
finally
{
transaction.Dispose();
}
}
}
}
but when register this interceptor it will apply to all methods. I have a service class with a repository injected having CRUD methods.
I don't want a transaction to be opened for query methods.
I read this link but I cannot figure out how to apply it to my code
http://docs.autofac.org/en/latest/advanced/adapters-decorators.html#decorators
I don't know who to refactor my TransactionalInterceptor (and register it) to use it in a class like this code
[Intercept(typeof(LoggerInterceptor))] //logger
public class SomeService : ISomeService
{
private readonly ISomeRepository someRepository;
public SomeService(SomeRepository someRepository)
{
this.someRepository = someRepository;
}
public IEnumerable<SomeDto> GetAll()
{
// code
}
public SomeDto GetById()
{
// code
}
[Transactional]
public int Create(SomeDto someDto)
{
// code to insert
}
}
The invocation parameter of the Intercept method contains a Method property which is a MethodInfo of the method currently intercepted.
You can use this property to do what you want.
For example by using the method name :
public void Intercept(IInvocation invocation)
{
if (invocation.MethodInvocationTarget.Name != nameof(ISomeService.Create))
{
invocation.Proceed();
return;
}
using (var transaction = ...)
{
try
{
invocation.Proceed();
transaction.Commit();
}
catch
{
transaction.Rollback();
}
finally
{
transaction.Dispose();
}
}
}
or based on an attribute from the target method :
if (!invocation.MethodInvocationTarget
.CustomAttributes
.Any(a => a.AttributeType == typeof(TransactionalAttribute)))
You can also use the IInterceptorSelector type but it requires more work to register it with Autofac
I solved the problem with ProxyGenerationHook. See the answer
Create your custom attribute for selecting which method to intercept. This attribute's target should be Method.
[System.AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
sealed class UseInterceptorAttribute : Attribute
{
public UseInterceptorAttribute()
{
}
}
Create your service interface and service class:
public interface ISomeService
{
void GetWithoutInterceptor();
[UseInterceptor]
void GetWithInterceptor();
}
public class SomeService
{
void GetWithoutInterceptor()
{
//This method will not be intercepted...
}
[UseInterceptor]
void GetWithInterceptor()
{
//This method will be intercepted...
}
}
Create your ProxyGenerationHook
public class SomeServiceProxyGenerationHook : IProxyGenerationHook
{
public void MethodsInspected()
{
}
public void NonProxyableMemberNotification(Type type, MemberInfo memberInfo)
{
}
public bool ShouldInterceptMethod(Type type, MethodInfo methodInfo)
{
return methodInfo
.CustomAttributes
.Any(a => a.AttributeType == typeof(UseInterceptorAttribute));
}
}
Don't use attributes for enabling interceptors. Enable it when
registering your service like this:
public class AutofacDependencyResolver
{
private readonly IContainer _container;
public AutofacDependencyResolver()
{
_container = BuildContainer();
}
private IContainer BuildContainer()
{
var proxyGenerationOptions = new ProxyGenerationOptions(new ProductServiceProxyGenerationHook());
builder.RegisterType<SomeService>()
.As<ISomeService>()
.EnableInterfaceInterceptors(proxyGenerationOptions)
.InterceptedBy(typeof(TransactionalInterceptor))
builder.Register(c => new TransactionalInterceptor());
return builder.Build();
}
public T GetService<T>()
where T:class
{
var result = _container.TryResolve(out T serviceInstance);
return serviceInstance ?? throw new Exception($"The service could not found: {nameof(T)}");
}
}
This solution is following this article
Also I uploaded the minimal example about this solution.
also can try, it is simple https://fs7744.github.io/Norns.Urd/index.html
public class AddTenInterceptorAttribute : AbstractInterceptorAttribute
{
public override void Invoke(AspectContext context, AspectDelegate next)
{
next(context);
AddTen(context);
}
private static void AddTen(AspectContext context)
{
if (context.ReturnValue is int i)
{
context.ReturnValue = i + 10;
}
else if(context.ReturnValue is double d)
{
context.ReturnValue = d + 10.0;
}
}
public override async Task InvokeAsync(AspectContext context, AsyncAspectDelegate next)
{
await next(context);
AddTen(context);
}
}
[AddTenInterceptor]
public interface IGenericTest<T, R> : IDisposable
{
// or
//[AddTenInterceptor]
T GetT();
}

Catch derived class Exceptions in base class with different methods and arguments

I'm trying to make something like base "exception handler" thing. So this base class will try-catch exceptions when any method (with any number of parameters) in derived class gets invoked. I'm not good in describing this with words, so here is the scenario:
public abstract BaseClass
{
Exception _ex;
public Exception LastKnownException
{
get
{
return this._ex;
}
}
//...
//what do I do here to assign the value of above property when some random exception occur in derived class?
//...
//The closest I can get...
public void RunMethod(Action method)
{
try
{
method.Invoke();
}
catch (Exception ex)
{
this._ex = ex;
}
}
}
public class DerivedClass : BaseClass
{
public void DoRandomMethod(int couldBeOfAnyTypeHere, bool andIndefiniteNumberOfThese)
{
bool result = false;
var someObject = new OtherClass(couldBeOfAnyTypeHere, out andIndefiniteNumberOfThese);
someObject.DoInternalWork(result); // <-- here is where I need the base class to take care if any exception should occur
}
public int AnotherMethod(int? id)
{
if (!id.HasValue)
id = Convert.ToInt32(Session["client_id"]);
var someOtherObject = new OtherClassB(id.Value);
return someOtherObject.CheckSomething(); // <-- and catch possible exceptions for this one too
}
//The closest I can get... (see base class implementation)
public List<RandomClass> GetSomeListBy(int id)
{
RunMethod(() =>
string[] whateverArgs = new[] { "is", "this", "even", "possible?" };
YetAnotherStaticClass.GetInstance().ExecuteErrorProneMethod(whateverArgs); // <-- Then when something breaks here, the LastKnownException will have something
);
}
}
public class TransactionController : Controller
{
public ActionResult ShowSomething()
{
var dc = new DerivedClass();
dc.DoRandomMethod(30, true);
if (dc.LastKnownException != null)
{
//optionally do something here
return RedirectToAction("BadRequest", "Error", new { ex = dc.LastKnownException });
}
else
{
return View();
}
}
}
EDIT: My simple approach will work, only, I don't want to have to wrap all methods with this lambda-driven RunMethod() method all the time -- I need the base class to somehow intercept any incoming exception and return the Exception object to the derived class without throwing the error.
Any ideas would be greatly appreciated. And thanks in advance!
I think you should consider using the event System.AppDomain.UnhandledException
This event will be raised whenever an exception occurs that is not handled.
As you don't clutter your code with the possibilities of exception, your code will be much better readable. Besides it would give derived classes the opportunity to catch exceptions if they expect ones, without interfering with your automatic exception catcher.
Your design is such, that if someone calls several functions of your derived class and then checks if there are any exceptions the caller wouldn't know which function caused the exception. I assume that your caller is not really interested in which function causes the exception. This is usually the case if you only want to log exception until someone investigates them.
If that is the case consider doing something like the following:
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
var ex = e.ExceptionObject as Exception;
if (ex != null)
logger.LogException(ex);
// TODO: decide whether to continue or exit.
}
If you really want to do this only for your abstract base class
public abstract BaseClass
{
private List<Exception> unhandledExceptions = new List<Exception>();
protected BaseClass()
{
AppDomain.CurrentDomain.UnhandledException += UnhandledException;
}
private void UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
var ex = e.ExceptionObject as Exception;
if (ex != null)
this.UnhandledExceptions.Add(ex);
}
public List<Exception> LastKnownExceptions
{
get { return this.unhandledExceptions; }
}
I had a similar requirement for catching exceptions, but used a specific implementation (i.e. not an abstract class) to encapsulate the handling of errors.
Please note this takes in an argument for any expected exceptions (params Type[] catchableExceptionTypes), but of course you can modify to suit your own requirements.
public class ExceptionHandler
{
// exposes the last caught exception
public Exception CaughtException { get; private set; }
// allows a quick check to see if an exception was caught
// e.g. if (ExceptionHandler.HasCaughtException) {... do something...}
public bool HasCaughtException { get; private set; }
// perform an action and catch any expected exceptions
public void TryAction(Action action, params Type[] catchableExceptionTypes)
{
Reset();
try
{
action();
}
catch (Exception exception)
{
if (ExceptionIsCatchable(exception, catchableExceptionTypes))
{
return;
}
throw;
}
}
// perform a function and catch any expected exceptions
// if an exception is caught, this returns null
public T TryFunction<T>(Func<T> function, params Type[] catchableExceptionTypes) where T : class
{
Reset();
try
{
return function();
}
catch (Exception exception)
{
if (ExceptionIsCatchable(exception, catchableExceptionTypes))
{
return null;
}
throw;
}
}
bool ExceptionIsCatchable(Exception caughtException, params Type[] catchableExceptionTypes)
{
for (var i = 0; i < catchableExceptionTypes.Length; i++)
{
var catchableExceptionType = catchableExceptionTypes[i];
if (!IsAssignableFrom(caughtException, catchableExceptionType)) continue;
CaughtException = caughtException;
HasCaughtException = true;
return true;
}
return false;
}
static bool IsAssignableFrom(Exception exception, Type type)
{
if (exception.GetType() == type) return true;
var baseType = exception.GetType().BaseType;
while (baseType != null)
{
if (baseType == type) return true;
baseType = baseType.BaseType;
}
return false;
}
void Reset()
{
CaughtException = null;
HasCaughtException = false;
}
}

Is it possible to get rid of the TClient generic type in the Service class

For WCF clients, I have a IServiceProxyFactory interface to set credentials.
public interface IServiceProxyFactory<T>
{
T GetServiceProxy();
}
public class ServiceProxy1 : IServiceProxyFactory<ServiceClient1>
{
public ServiceClient1 GetServiceProxy()
{
var client = new ServiceClient1();
// set credentials here
return client;
}
}
public class ServiceProxy2 : IServiceProxyFactory<ServiceClient2> {
// ...
}
From the question What is the best workaround for the WCF client `using` block issue?, and I created a helper as follows:
public static class Service<TProxy, TClient>
where TProxy : IServiceProxyFactory<TClient>, new()
where TClient : ICommunicationObject
{
public static IServiceProxyFactory<TClient> proxy = new TProxy();
public static void Use(Action<TClient> codeBlock)
{
TClient client = default(TClient);
bool success = false;
try
{
client = proxy.GetServiceProxy();
codeBlock(client);
((ICommunicationObject)client).Close();
success = true;
}
finally
{
if (!success)
{
((ICommunicationObject)client).Abort();
}
}
}
}
And I use the helper as:
Service<ServiceProxy1, ServiceClient1>.Use(svc => svc.Method());
Question:
Is there a way where I can get rid of the TClient or TProxy(updated) type so that I can call using:
Service<ServiceProxy1>.Use(svc => svc.Method());
OR (updated)
Service<ServiceClient1>.Use(svc => svc.Method());
Is there a better way than to use ICommunicationObject for Close() and Abort()?
Code
partial class TestClass {
public static void TestMethod() {
Service<ServiceProxy1>.Use(svc => svc.Method());
Service<ServiceProxy1>.Use(svc => svc.Method());
Service<ServiceProxy1>.Use(svc => svc.Method());
Service<ServiceProxy2>.Use(svc => svc.Method());
}
}
public partial interface IServiceProxyFactory<T> {
T GetServiceProxy();
}
public partial class Service<T> where T: ServiceProxy, new() {
public static void Use(Action<T> codeBlock) {
using(var client=ServiceProxy.GetServiceProxy<T>().GetServiceProxy() as T)
try {
codeBlock(client);
}
catch {
throw;
}
}
}
public abstract partial class ServiceProxy: CommunicationObject, IDisposable {
public static T GetServiceProxy<T>() where T: ServiceProxy, new() {
var proxy=m_List.FirstOrDefault(x => typeof(T).Equals(x.GetType())) as T;
if(null==proxy) {
proxy=new T();
m_List.Add(proxy);
}
return proxy;
}
public abstract ServiceProxy GetServiceProxy();
public abstract void Method();
protected virtual void Dispose(bool disposing) {
lock(ThisLock)
if(!this.IsDisposed&&disposing) {
this.Close();
if(!this.IsDisposed)
this.Abort();
}
}
public void Dispose() {
this.Dispose(true);
GC.SuppressFinalize(this);
}
~ServiceProxy() {
this.Dispose(false);
}
static List<ServiceProxy> m_List=new List<ServiceProxy>();
}
public partial class ServiceProxy1: ServiceProxy {
protected override IAsyncResult OnBeginClose(
TimeSpan timeout, AsyncCallback callback, object state
) {
throw new NotImplementedException();
}
protected override IAsyncResult OnBeginOpen(
TimeSpan timeout, AsyncCallback callback, object state
) {
throw new NotImplementedException();
}
protected override void OnAbort() {
}
protected override void OnEndClose(IAsyncResult result) {
}
protected override void OnEndOpen(IAsyncResult result) {
}
protected override void OnClose(TimeSpan timeout) {
}
protected override void OnOpen(TimeSpan timeout) {
}
protected override TimeSpan DefaultCloseTimeout {
get {
return TimeSpan.Zero;
}
}
protected override TimeSpan DefaultOpenTimeout {
get {
return TimeSpan.Zero;
}
}
public override ServiceProxy GetServiceProxy() {
var client=new ServiceProxy1();
// set credentials here
return client;
}
public override void Method() {
}
}
public partial class ServiceProxy2: ServiceProxy1 {
public override ServiceProxy GetServiceProxy() {
var client=new ServiceProxy2();
// set credentials here
return client;
}
}
Something to mention:
lock are safe to be re-entered
It's impossible for me to do the exactly same declaration of a reversed inference from T to a type of any Generic<T>, such as from ServiseClient to ServiceProxy<ServiceClient>.
According to 2, ServiceProxy and ServiceClient are just the same thing in the code, so there's no ServiceClient.
ServiceProxy itself is abstract. For the requirement of ServiceClient need to be convert to ICommunicationObject and according to 3 plus for the convenience reason, ServiceProxy derives from CommunicationObject; and then for Is there a better way than ... stuff, it implements IDisposible
For the static instances of a concrete class which inherits ServiceProxy, each would have only one instance, and stored in m_List, and calling the static generic version of GetServiceProxy<T>() just get them. This appears it's more like the flyweight pattern.
According to 5, the interface IServiceProxyFactory<T> is not used at all, just put it there for look and feel happy.
The instance version of GetServiceProxy() is kept the original usage, but concrete class would need to override it.
In the Use method, the created client is used with a using statement. I've read the Avoiding Problems with the Using Statement, but seems I'm not aware the strategy you would like to handle the exceptions, thus I just try and rethrow.
According to 1, I'm consider a thread safe way by lock to dispose atomically, the inherited IsDisposed and ThisLock are used. The Close and Abort are doing there accordingly.
Oh ten! The class ServiceProxy2 and ServiceProxy1 are just for sample, and ServiceProxy2 derives from ServiceProxy1.
The code looks verbose but in fact very simple design. Just report me for the issues and I'll try to correct it. Wish helps anda GOOD LOCK!
I achieved it by merging ServiceProxy1 class into ServiceClient1 by using ServiceClient1 : IServiceProxyFactory<ServiceClient1> trick.
public interface IServiceProxyFactory<T>
{
// can have a better name like SetCredentials()
T GetServiceProxy();
}
// Got rid of ServiceProxy1 class
public partial class ServiceClient1 : IServiceProxyFactory<ServiceClient1>
{
public ServiceClient1 GetServiceProxy()
{
var client = this;
// set credentials here
//client.ClientCredentials = "";
return client;
}
}
public partial class ServiceClient2 : IServiceProxyFactory<ServiceClient2> { ... }
public static class ServiceMod<TClient>
where TClient : class, ICommunicationObject, IServiceProxyFactory<TClient>, new()
{
public static TReturn Use<TReturn>(Func<TClient, TReturn> codeBlock)
{
TClient client = default(TClient);
bool success = false;
try
{
client = new TClient().GetServiceProxy();
TReturn result = codeBlock(client);
client.Close();
success = true;
return result;
}
finally
{
if (!success)
{
client.Abort();
}
}
}
}
And now I can do:
Service<ServiceClient1>.Use(svc => svc.Method());

Calling WCF service using extension method

I've written an extension method for use with WCF services that keeps all the disposal and exception handling logic in one place. The method is as follows:
public static TResult CallMethod<TChannel, TResult>(
this ClientBase<TChannel> proxy,
Func<TResult> func) where TChannel : class
{
proxy.ThrowIfNull("proxy");
func.ThrowIfNull("func");
try
{
// set client credentials
return func();
}
finally
{
if (proxy != null)
{
try
{
if (proxy.State != CommunicationState.Faulted)
{
proxy.Close();
}
else
{
proxy.Abort();
}
}
catch (CommunicationException)
{
proxy.Abort();
}
catch (TimeoutException)
{
proxy.Abort();
}
catch (Exception)
{
proxy.Abort();
throw;
}
}
}
}
The method will be used like this:
public int CreateBusinessObject(BusinessObject item)
{
MyServiceClient proxy = new MyServiceClient();
return proxy.CallMethod(() => proxy.CreateBusinessObject(item));
}
My question really is whether this would be better as a static method which creates the service proxy? I'm slightly worried about my current implementation. Should the construction of the proxy be inside the try/catch? My current understanding is that if the constructor fails, there is nothing to dispose of anyway.
If the constructor fails, the entire object is in an invalid state. You should not be worried about disposing in this case.
A nice test for this is what would happen when you execute the following:
class Program
{
static void Main(string[] args)
{
using (new TestClass())
{
Console.WriteLine("In using");
}
}
class TestClass : IDisposable
{
public TestClass()
{
throw new Exception();
}
public void Dispose()
{
Console.WriteLine("Disposed");
}
}
}
The result is that the Disposing never gets reached. This is what happens when the constructor fails.

Custom lifetime management in DI containers (wcf proxy: Unity vs Castle Windsor)

I've found nice post: Singleton WCF Proxy.
It is about the implementation of WCF proxy life scope using Castle Windsor DI container.
Implementation of the abstract class AbstractLifestyleManager from Castle.MicroKernel.Lifestyle namespace overrides 3 methods: Resolve, Dispose and Release. In the Release method we have access to the context, from which we can resolve service instance.
I've copied the code from that post (with a small change) below:
public class SingletonWCFProxyLifestyleManager : AbstractLifestyleManager
{
private object instance;
public override object Resolve(Castle.MicroKernel.CreationContext context)
{
lock (base.ComponentActivator)
{
if (this.instance == null)
{
this.instance = base.Resolve(context);
}
else
{
ICommunicationObject communicationObject = this.instance as ICommunicationObject;
if (communicationObject != null &&
communicationObject.State == CommunicationState.Faulted)
{
try
{
communicationObject.Abort();
}
catch { }
this.instance = base.Resolve(context);
}
}
}
return this.instance;
}
public override void Dispose()
{
if (this.instance != null)
{
base.Release(this.instance);
}
}
public override void Release(object instance)
{
}
}
I would like to provide the same functionality using Unity container. It looks like the LifetimeManager class from Microsoft.Practices.Unity namespace (and optionally IRequiresRecovery interface) is dedicated for that.
All methods that class is providing are shown below:
public class SingletonWCFProxyLifestyleManager : LifetimeManager, IRequiresRecovery
{
public override object GetValue()
{
throw new NotImplementedException();
}
public override void RemoveValue()
{
throw new NotImplementedException();
}
public override void SetValue(object newValue)
{
throw new NotImplementedException();
}
#region IRequiresRecovery Members
public void Recover()
{
throw new NotImplementedException();
}
#endregion
}
And here is the question:
How to provide the same functionality in the second example (using Unity), as it was done in the first example (using Castle Windsor) ?
(PS: There is no access to the context of the container, so how I can resolve the object ?).
Regards
I'll try to answer my question (I hope that correctly..).
I've found this post Writing Custom Lifetime Managers. I've been trying to implement solution I've described previously in details, based on that post and the previous one: Singleton WCF Proxy.
Below is what I have created. Of course I have to test that code. For the first look, it is rather ok, but I'll see later.
public class SingletonWCFProxyLifestyleManager : LifetimeManager, IRequiresRecovery, IDisposable
{
private static readonly object _locker = new object();
private Guid _key;
public SingletonWCFProxyLifestyleManager()
{
_key = Guid.NewGuid();
}
public override object GetValue()
{
Monitor.Enter(_locker);
object result = Storage.Instance.Get(_key);
if (result != null)
{
ICommunicationObject communicationObject = result
as ICommunicationObject;
//If the proxy is in faulted state, it's aborted and a new proxy is created
if (communicationObject != null &&
communicationObject.State == CommunicationState.Faulted)
{
try
{
communicationObject.Abort();
}
catch
{
}
Dispose();
return null; //Return before releasing monitor
}
Monitor.Exit(_locker);
}
return result;
}
public override void RemoveValue()
{
}
public override void SetValue(object newValue)
{
Storage.Instance.Set(_key, newValue);
TryToReleaseMonitor();
}
#region IRequiresRecovery Members
public void Recover()
{
TryToReleaseMonitor();
}
#endregion
private void TryToReleaseMonitor()
{
try
{
Monitor.Exit(_locker);
}
catch(SynchronizationLockException)
{
} // This is ok, just means we don't hold the lock
}
#region IDisposable Members
public void Dispose()
{
object result = Storage.Instance.Get(_key);
if (result != null)
{
try
{
Storage.Instance.RemoveAndDispose(_key);
}
catch
{
ICommunicationObject communicationObject = result as ICommunicationObject;
if (communicationObject != null)
{
communicationObject.Abort();
}
}
}
}
#endregion
}
Storage utility class has been created for caching instances of services (it contains hashtable ans a few utility methods, like Get or RemoveAndDispose), but it is too simple for pasting it here.

Categories

Resources