Castle Dynamic Proxy of Interface and not Derived Class - c#

namespace DynamicInterception
{
public class Calculator
{
public virtual int Div(int a, int b)
{
try
{
return a / b;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message.ToString());
return 0;
}
}
}
[Serializable]
public abstract class Interceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
ExecuteBefore(invocation);
invocation.Proceed();
ExecuteAfter(invocation);
}
protected abstract void ExecuteAfter(IInvocation invocation);
protected abstract void ExecuteBefore(IInvocation invocation);
}
public class CalculatorInterceptor : Interceptor
{
protected override void ExecuteBefore(Castle.DynamicProxy.IInvocation invocation)
{
Console.WriteLine("Start: {0}", invocation.Method.Name);
}
protected override void ExecuteAfter(Castle.DynamicProxy.IInvocation invocation)
{
Console.WriteLine("End: {0}", invocation.Method.Name);
}
}
class Program
{
static void Main(string[] args)
{
ProxyGenerator generator = new ProxyGenerator();
Calculator c = generator.CreateClassProxy<Calculator>(new CalculatorInterceptor());
var r = c.Div(11, 0);
Console.ReadKey();
}
}
}
Is it possible to replace public virtual int Div(int a,int b)
with interface
interface ICalculator
{
int Div(int a, int b);
}
How then should look like proxy declaration?
ProxyGenerator generator = new ProxyGenerator();
Calculator c = generator.CreateClassProxy<Calculator>(new CalculatorInterceptor());

If you want to add an interface to the Calculator and to execute those 2 lines
it will work the same:
public interface ICalculator
{
int Div(int a, int b);
}
public class Calculator : ICalculator
{
public int Div(int a, int b)
{
try
{
return a / b;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message.ToString());
return 0;
}
}
}
ProxyGenerator generator = new ProxyGenerator();
Calculator c = generator.CreateClassProxy<Calculator>(new CalculatorInterceptor());
But you didn't really do anything by that - you are still creating the proxy for a concrete derived type. I assume you want something like "CreateClassProxy<ICalculator>". That won't work because the CreateClassProxy has a generic constraint on where TClass : class.
What you do have is a variety of CreateInterfaceProxt.. Methods which you can try. But still a naive execution like the following won't work:
ICalculator c = generator.CreateInterfaceProxyWithoutTarget<ICalculator>(new CalculatorInterceptor());
c.Div(1, 2);
It will execute, call the interceptor and will fail when running the invocation.Proceed(); with the error:
System.NotImplementedException This is a DynamicProxy2 error: The
interceptor attempted to 'Proceed' for method 'Int32 Div(Int32,
Int32)' which has no target. When calling method without target there
is no implementation to 'proceed' to and it is the responsibility of
the interceptor to mimic the implementation (set return value, out
arguments etc)
So as the good indicative (seriously) errors of Castle specify - you must somehow have an implementation for it - or by indicating it yourself in the interceptor - of by having a Component registered for that interface.
Instead you can do like this: (Check comments in code)
ProxyGenerator generator = new ProxyGenerator();
ICalculator calculator = new Calculator();
var proxyCalculator = generator.CreateInterfaceProxyWithTarget(typeof(ICalculator),calculator, new CalculatorInterceptor());
calculator.Div(1, 2); // Will execute but will not be intercepted
((ICalculator)proxyCalculator).Div(11, 0); //Will execute and will be intercepted
But after saying all I said above, if the purpose behind all of this is to have an interceptor intercept your method then just just the "good-old" registering to the container:
WindsorContainer container = new WindsorContainer();
container.Register(
Component.For<CalculatorInterceptor>(),
Component.For<ICalculator>()
.ImplementedBy<Calculator>()
.Interceptors<CalculatorInterceptor>());
var calculator = container.Resolve<ICalculator>();
calculator.Div(1, 0);
// Output:
// Start: Div
// Attempted to divide by zero
// End: Div

Related

How to choose the right strategy at runtime when implementing the strategy pattern?

Problem description
Consider the following implementation of the strategy pattern:
// this is the strategy definition
public interface ICalculator
{
int ComputeResult(int a, int b);
}
// this is an implementation of the strategy
public sealed class SumCalculator: ICalculator
{
public int ComputeResult(int a, int b) => a + b;
}
// this is another implementation of the strategy
public sealed class SubtractionCalculator: ICalculator
{
public int ComputeResult(int a, int b) => a - b;
}
Let's suppose we need to write some client code for the ICalculator service. The client code is given the following input data:
an integer number, via the variable a
another integer number, via the variable b
contextual information used to decide which strategy needs to be used. Let's suppose to have an enum named TaskType whose possible values are Sum and Subtract.
From a functional perspective, the client code should do something like this:
int a = GetFirstOperand();
int b = GetSecondOperand();
TaskType taskType = GetTaskType();
ICalculator calculator = null;
switch(taskType)
{
case TaskType.Sum:
calculator = new SumCalculator();
break;
case TaskType.Subtract:
calculator = new SubtractionCalculator();
break;
default:
throw new NotSupportedException($"Task type {taskType} is not supported");
}
int result = calculator.ComputeResult(a,b);
Console.Writeline($"The result is: {result}");
Consider now a codebase using dependency injection and delegating object creation and lifetime management to a DI container. In this case, the client code of the ICalculator service can't directly take the responsibility of creating objects.
What I'm trying to find is, basically, an elegant and effective way to solve this problem.
What I usually do in this scenario
This is what I usually do to solve this problem. I call this design pattern the composite design pattern, but I'm quite sure this is not exactly the pattern named composite design pattern in the gang of four book.
First of all, a reshape of the ICalculator interface is needed (more on this later):
public interface ICalculator
{
int ComputeResult(int a, int b, TaskType taskType);
bool CanHandleTask(TaskType taskType);
}
The existing interface implementations need to be changed:
public sealed class SumCalculator: ICalculator
{
public int ComputeResult(int a, int b, TaskType taskType)
{
if (!this.CanHandleTask(taskType))
{
throw new InvalidOperationException($"{nameof(SumCalculator)} cannot handle task {taskType}");
}
return a + b;
}
public bool CanHandleTask(TaskType taskType) => taskType == TaskType.Sum;
}
public sealed class SubtractionCalculator: ICalculator
{
public int ComputeResult(int a, int b, TaskType taskType)
{
if (!this.CanHandleTask(taskType))
{
throw new InvalidOperationException($"{nameof(SubtractionCalculator)} cannot handle task {taskType}");
}
return a - b;
}
public bool CanHandleTask(TaskType taskType) => taskType == TaskType.Subtract;
}
A third implementation of the ICalculator interface needs to be written. I call this object the composite object:
public sealed class CompositeCalculator: ICalculator
{
private readonly IEnumerable<ICalculator> _calculators;
public CompositeCalculator(IEnumerable<ICalculator> calculators)
{
_calculators = calculators ?? throw new ArgumentNullException(nameof(calculators));
}
public int ComputeResult(int a, int b, TaskType taskType)
{
if (!this.CanHandleTask(taskType))
{
throw new InvalidOperationException($"{nameof(CompositeCalculator)} cannot handle task {taskType}");
}
var handler = _calculators.First(x => x.CanHandleTask(taskType));
return handler.ComputeResult(a, b, taskType);
}
public bool CanHandleTask(TaskType taskType) => _calculators.Any(x => x.CanHandleTask(taskType));
}
This is the client code of ICalculator:
// this class encapsulates the client code of ICalculator
public sealed class AnotherService
{
private readonly ICalculator _calculator;
public AnotherService(ICalculator calculator)
{
_calculator = calculator ?? throw new ArgumentNullException(nameof(calculator));
}
public void DoSomething()
{
// code omitted for brevity
int a = ...;
int b = ...;
TaskType taskType = ...;
var result = _calculator.ComputeResult(a, b, taskType);
Console.Writeline($"The result is {result}");
}
}
Finally, here is the registration of the ICalculator interface in the DI container:
services.AddSingleton<SumCalculator>();
services.AddSingleton<SubtractionCalculator>();
services.AddSingleton<ICalculator>(sp =>
{
var calculators = new List<ICalculator>
{
sp.GetRequiredService<SumCalculator>(),
sp.GetRequiredService<SubtractionCalculator>()
};
return new CompositeCalculator(calculators);
});
This pattern works, but I don't like the fact that the ICalculator interface needs to be modified in order to introduce the CanHandleTask method and the extraneous parameter taskType to the ComputeResult method.
The original definition of the ICalculator interface (see the Problem description above) seems to be a more natural definition for a service able to compute a result using two integer numbers as input to the computation.
An alternative solution
An alternative solution to this problem is introducing a factory object for the ICalculator interface. This is somewhat similar to the IHttpClientFactory interface introduced in .NET core.
This way we can keep the original definition for the ICalculator interface:
public interface ICalculator
{
int ComputeResult(int a, int b);
}
We need to introduce a factory object for ICalculator instances:
public interface ICalculatorFactory
{
ICalculator CreateCalculator(TaskType taskType);
}
These are the implementations of the ICalculator interface (no more need for the composite object):
public sealed class SumCalculator: ICalculator
{
public int ComputeResult(int a, int b) => a + b;
}
public sealed class SubtractionCalculator: ICalculator
{
public int ComputeResult(int a, int b) => a - b;
}
This is the new version of the client code:
// this class encapsulates the client code of ICalculator
public sealed class AnotherService
{
private readonly ICalculatorFactory _calculatorFactory;
public AnotherService(ICalculatorFactory calculatorFactory)
{
_calculatorFactory = calculatorFactory ?? throw new ArgumentNullException(nameof(calculatorFactory));
}
public void DoSomething()
{
// code omitted for brevity
int a = ...;
int b = ...;
TaskType taskType = ...;
var calculator = _calculatorFactory.CreateCalculator(taskType);
var result = calculator.ComputeResult(a, b);
Console.Writeline($"The result is {result}");
}
}
The concrete implementation for the ICalculatorFactory interface delegates the object creation to the DI container and is defined inside the composition root (because it depends on the DI container directly):
public sealed class ServiceProviderCalculatorFactory: ICalculatorFactory
{
private readonly IServiceProvider _serviceProvider;
public ServiceProviderCalculatorFactory(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
}
public ICalculator CreateCalculator(TaskType taskType)
{
switch(taskType)
{
case TaskType.Sum:
return _serviceProvider.GetRequiredService<SumCalculator>();
case TaskType.Subtract:
return _serviceProvider.GetRequiredService<SubtractionCalculator>();
default:
throw new NotSupportedException($"Task type {taskType} is not supported");
}
}
}
Finally, here is the service registration on the DI container:
services.AddSingleton<SumCalculator>();
services.AddSingleton<SubtractionCalculator>();
services.AddSingleton<ICalculatorFactory, ServiceProviderCalculatorFactory>();
The main advantange of this solution is avoiding all of the CanHandle ceremony of the composite pattern described above.
Question
Is there a better or canonical way to resolve this problem ?
Consider now a codebase using dependency injection and delegating object creation and lifetime management to a DI container.
It is possible to inject dependencies through constructor. Let me show an example.
I've little bit changed names. So now enum will look like this:
public enum OperationType
{
Sum,
Subtract
}
This is your abstraction:
public interface IOperation
{
int Compute(int a, int b);
}
And its concrete implementations:
public class SumOperation : IOperation
{
public int Compute(int a, int b) => a + b;
}
public class SubtractionOperation : IOperation
{
public int Compute(int a, int b) => a - b;
}
And then we inject all dependencies through constructor to allow future clients of CalculatorOperationFactory to use concrete implementations of IOperation by operation type:
public class CalculatorOperationFactory
{
private Dictionary<OperationType, IOperation> _operationByType;
public CalculatorOperationFactory(SumOperation sumOperation,
SubtractionOperation subtractionOperation)
{
_operationByType = new Dictionary<OperationType, IOperation>()
{
{ OperationType.Sum, sumOperation },
{ OperationType.Subtract, subtractionOperation },
};
}
public IOperation GetInstanceByOperationType(OperationType taskType)
=> _operationByType[taskType];
}
And then you can inject CalculatorOperationFactory to AnotherService:
public class AnotherService
{
CalculatorOperationFactory _calculatorFactory;
public AnotherService(CalculatorOperationFactory calculatorFactory)
{
_calculatorFactory = calculatorFactory;
}
public void DoSomething()
{
// code is omitted for brevity
int a = 0;
int b = 1;
OperationType taskType = OperationType.Sum;
IOperation operation = _calculatorFactory
.GetInstanceByTaskType(taskType);
var result = operation.Compute(a, b);
}
}
And your dependencies will look like this:
services.AddSingleton<SumOperation>();
services.AddSingleton<SubtractionOperation>();
services.AddSingleton<CalculatorFactory>();
Maybe a slight variation of the first solution:
public interface ICalculatorStrategy
{
int ComputeResult(int a, int b);
TaskType TaskType { get; }
}
public class SumCalculator : ICalculatorStrategy
{
public int ComputeResult(int a, int b) => a + b;
public TaskType TaskType => TaskType.Sum;
}
public sealed class SubtractionCalculator: ICalculatorStrategy
{
public int ComputeResult(int a, int b) => a - b;
public TaskType TaskType => TaskType.Subtract;
}
public interface ICalculator
{
public int ComputeResult(int a, int b, TaskType type);
}
public class Calculator : ICalculator
{
private readonly IEnumerable<ICalculatorStrategy> _strategies;
public Calculator(IEnumerable<ICalculatorStrategy> strategies) =>
_strategies = strategies;
public int ComputeResult(int a, int b, TaskType type)
{
var strategy = _strategies.FirstOrDefault(s => s.TaskType == type)
?? throw new InvalidOperationException($"No strategy found for type {type}");
return strategy.ComputeResult(a, b);
}
}
MS DI container can inject the IEnumerable<ICalculatorStrategy> for you.
services.AddTransient<ICalculatorStrategy, SumCalculator>();
services.AddTransient<ICalculatorStrategy, SubtractionCalculator>();
services.AddTransient<ICalculator, Calculator>();
I would argue that second approach is quite qood. Another way you can handle it is by switching to container which supports keyed dependencies like Autofac and use it to generate a Func factory as in this snippet created some years ago:
var builder = new ContainerBuilder();
builder.RegisterType<ImplOne>()
.Keyed<IDependency>(MyTypeEnum.TypeOne)
.SingleInstance();
builder.RegisterType<ImplTwo>()
.Keyed<IDependency>(MyTypeEnum.TypeTwo)
.SingleInstance();
builder.Register((c, p) =>
{
var type = p.TypedAs<MyTypeEnum>();
var resolve = c.Resolve<IIndex<MyTypeEnum, IDependency>>();
return resolve[type];
});
var container = builder.Build();
Func<MyTypeEnum, IDependency> factory = container.Resolve<Func<MyTypeEnum, IDependency>>();
var dependency = factory(MyTypeEnum.TypeOne);

why need to use virtual and override?

i have created same name methods in base and derived classes and i am able to create
class Program
{
public void CalculateArea(int a,int b)
{
Console.WriteLine(a*b);
}
}
class progrmm1:Program
{
public void CalculateArea(int a ,int b)
{
Console.WriteLine(a + b);
}
static void Main(string[] args)
{
progrmm1 obj = new progrmm1();
Program obj1 = new Program();
obj.CalculateArea(4,5);
obj1.CalculateArea(4,5);
Console.ReadLine();
}
}
then why i need to use virtual and override
If you don't use virtual and override then you are not taking advantage of polymorphism. Basically the CalculateArea in the derived class is hiding the one in the base class. That means that if you reference an object of the derived class type as the base it will call the CalculateArea in the base class instead of the derived one. Where as if you use virtual and override it would call the Derived method even if it where referenced as the Base.
For example with these classes
public class Base
{
public void DoSomething()
{
Console.WriteLine("Base.DoSomething");
}
}
public class Derived : Base
{
public void DoSomething()
{
Console.WriteLine("Derived.DoSomething");
}
}
This code
Base derivedAsBase = new Derived();
derivedAsBase.DoSomething();
will output
Base.DoSomething
but using virtual and override
public class Base
{
public virtual void DoSomething()
{
Console.WriteLine("Base.DoSomething");
}
}
public class Derived : Base
{
public override void DoSomething()
{
Console.WriteLine("Derived.DoSomething");
}
}
The same code
Base derivedAsBase = new Derived();
derivedAsBase.DoSomething();
will output
Derived.DoSomething
When overridden, the method on the most derived class is called. Observe this slightly modified code where I assign two Program instances. One from a Program and one from a program1:
class Program
{
public virtual void CalculateArea(int a, int b)
{
Console.WriteLine(a * b);
}
}
class progrmm1 : Program
{
public override void CalculateArea(int a, int b)
{
Console.WriteLine(a + b);
}
static void Main(string[] args)
{
Program obj = new progrmm1();
Program obj1 = new Program();
obj.CalculateArea(4, 5);
obj1.CalculateArea(4, 5);
Console.ReadLine();
}
}
OUTPUT:
9
20
And now, observe non-virtual:
class Program
{
public void CalculateArea(int a, int b)
{
Console.WriteLine(a * b);
}
}
class progrmm1 : Program
{
public void CalculateArea(int a, int b)
{
Console.WriteLine(a + b);
}
static void Main(string[] args)
{
Program obj = new progrmm1();
Program obj1 = new Program();
obj.CalculateArea(4, 5);
obj1.CalculateArea(4, 5);
Console.ReadLine();
}
}
OUTPUT
20
20
First you need to know about Virtual Method.
Basically A virtual method is a method that can be redefined in
derived classes. A virtual method has an implementation in a base
class as well as derived the class.
Example:
Let Suppose we have two classes, A and B. Class A has a public virtual method called Test. Class B, meanwhile, derives from class A and it provides a public override method called Test as well.
using System;
class A
{
public virtual void Test()
{
Console.WriteLine("A.Test");
}
}
class B : A
{
public override void Test()
{
Console.WriteLine("B.Test");
}
}
class Program
{
static void Main()
{
// Compile-time type is A.
// Runtime type is A as well.
A ref1 = new A();
ref1.Test();
// Compile-time type is A.
// Runtime type is B.
A ref2 = new B();
ref2.Test();
}
}
Output
A.Test
B.Test
Why would you need to use virtual methods?:
Your program may be designed in such a way that you do not know all the types of objects that will occur when it is executed. You can provide a standard (base) type and design around that type.
Then, you can re-implement important functionality depending on the more specific (derived) types. When you call a method on the base type, you invoke the more derived (and useful) method.

How use IInterceptor in Castle.DynamicProxy?

I wrote an example like this
Simple Calculator class :
public class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
}
implemented "IInterceptor" that provided by DynamicProxy
[Serializable]
public abstract class Interceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
ExecuteBefore(invocation);
invocation.Proceed();
ExecuteAfter(invocation);
}
protected abstract void ExecuteAfter(IInvocation invocation);
protected abstract void ExecuteBefore(IInvocation invocation);
}
Created an Interceptor class and inherited from "Interceptor" class
public class CalculatorInterceptor : Interceptor
{
protected override void ExecuteBefore(Castle.DynamicProxy.IInvocation invocation)
{
Console.WriteLine("Start");
}
protected override void ExecuteAfter(Castle.DynamicProxy.IInvocation invocation)
{
Console.WriteLine("End");
}
}
but when I used it NOT working !!!
static void Main(string[] args)
{
ProxyGenerator generator = new ProxyGenerator();
Calculator c = generator.CreateClassProxy<Calculator>(new CalculatorInterceptor());
var r = c.Add(11, 22);
Console.WriteLine(r);
Console.ReadKey();
}
I excepted to see something like this :
START
33
END
but only show
33
How I can correct it ?!
Try to make the method Add virtual.
public class Calculator
{
public virtual int Add(int a, int b)
{
return a + b;
}
}
The proxy generator creates a new class inheriting Calculator. Thus, the method Add gets an override to make interception possible.
The other option is to make an ICalculator interface
public interface ICalculator
{
int Add(int a, int b);
}
and inherit your class from this interface
public class Calculator : ICalculator
{
public int Add(int a, int b)
{
return a + b;
}
}
Your dynamic proxy would then use the CreateInterfaceProxyWithTarget method
var proxyGenerator = new ProxyGenerator();
ICalculator calculator = new Calculator()
var proxy = proxyGenerator.CreateInterfaceProxyWithTarget(
calculator,
ProxyGenerationOptions.Default,
new CalculatorInterceptor());
Console.WriteLine(proxy.Add(1, 2));
This gets rid of the virtual from your Calculator class, which in my opinion is bad design unless you have reason to override the method in the future.
You have to use the correct overload and pass in both the target object and the interceptor you wish to use. Method should look something like this:
var proxy = generator.CreateClassProxy<Calculator>(new Calculator(), new CalculatorInterceptor() );

Inheritance same methods implementation

I have the following code. (in c#)
interface 1:
public interface iBclass
{
int addition(int a);
int s(); //and more methods from this ......
}
interface 2:
public interface iAclass
{
int addition(int a);
//more methods.....
}
Class that inherits both interfaces:
public class dClass : iAclass , iBclass
{
int iAclass.addition(int a)
{
return 0;
}
int iBclass.addition(int a)
{
return 1;
}
public int s()
{
return 3;
}
}
the problem is i am not able to access the Method iAclass.addition(int a) and iBclass.addition(int a) with the d object.
dClass d = new dClass();
how can i access those method by 'd' object? and why those interface methods are not allow to define as public?
The interfaces are implemented explicitly. So you can only call them by using the interface:
dClass d = new dClass();
iAclass a = (iAclass)d;
a.addition(123); // Calls implementation for iAclass
iBclass b = (iBclass)d;
b.addition(123); // Calls implementation for iBclass
See this link for details.

Class inheriting from several Interfaces having same method signature

Say, I have three interfaces:
public interface I1
{
void XYZ();
}
public interface I2
{
void XYZ();
}
public interface I3
{
void XYZ();
}
A class inheriting from these three interfaces:
class ABC: I1,I2, I3
{
// method definitions
}
Questions:
If I implement like this:
class ABC: I1,I2, I3
{
public void XYZ()
{
MessageBox.Show("WOW");
}
}
It compiles well and runs well too!
Does it mean this single method implementation is sufficient for inheriting all the three Interfaces?
How can I implement the method of all the three interfaces and CALL THEM?
Something Like this:
ABC abc = new ABC();
abc.XYZ(); // for I1 ?
abc.XYZ(); // for I2 ?
abc.XYZ(); // for I3 ?
I know it can done using explicit implementation but I'm not able to call them. :(
If you use explicit implementation, then you have to cast the object to the interface whose method you want to call:
class ABC: I1,I2, I3
{
void I1.XYZ() { /* .... */ }
void I2.XYZ() { /* .... */ }
void I3.XYZ() { /* .... */ }
}
ABC abc = new ABC();
((I1) abc).XYZ(); // calls the I1 version
((I2) abc).XYZ(); // calls the I2 version
You can call it. You just have to use a reference with the interface type:
I1 abc = new ABC();
abc.XYZ();
If you have:
ABC abc = new ABC();
you can do:
I1 abcI1 = abc;
abcI1.XYZ();
or:
((I1)abc).XYZ();
During implementation in a class do not specify modifier o/w you will get compilation error, also specify the interface name to avoid ambiguity.You can try the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleCSharp
{
class Program
{
static void Main(string[] args)
{
MyClass mclass = new MyClass();
IA IAClass = (IA) mclass;
IB IBClass = (IB)mclass;
string test1 = IAClass.Foo();
string test33 = IBClass.Foo();
int inttest = IAClass.Foo2();
string test2 = IBClass.Foo2();
Console.ReadKey();
}
}
public class MyClass : IA, IB
{
static MyClass()
{
Console.WriteLine("Public class having static constructor instantiated.");
}
string IA.Foo()
{
Console.WriteLine("IA interface Foo method implemented.");
return "";
}
string IB.Foo()
{
Console.WriteLine("IB interface Foo method having different implementation. ");
return "";
}
int IA.Foo2()
{
Console.WriteLine("IA-Foo2 which retruns an integer.");
return 0;
}
string IB.Foo2()
{
Console.WriteLine("IA-Foo2 which retruns an string.");
return "";
}
}
public interface IA
{
string Foo(); //same return type
int Foo2(); //different return tupe
}
public interface IB
{
string Foo();
string Foo2();
}
}

Categories