Edit: Changed question title from "Does C# allow method overloading, PHP style (__call)?" - figured out it doesn't have much to do with actual question. Also edited question text.
What I want to accomplish is to proxy calls to a an instance of an object methods, so I could log calls to any of its methods.
Right now, I have code similar to this:
class ProxyClass {
static logger;
public AnotherClass inner { get; private set; }
public ProxyClass() { inner = new AnotherClass(); }
}
class AnotherClass {
public void A() {}
public void B() {}
public void C() {}
// ...
}
// meanwhile, in happyCodeLandia...
ProxyClass pc = new ProxyClass();
pc.inner.A(); // need to write log message like "method A called"
pc.inner.B(); // need to write log message like "method B called"
// ...
So, how can I proxy calls to an object instance in extensible way? Method overloading would be most obvious solution (if it was supported in PHP way). By extensible, meaning that I don't have to modify ProxyClass whenever AnotherClass changes.
In my case, AnotherClass can have any number of methods, so it wouldn't be appropriate to overload or wrap all methods to add logging.
I am aware that this might not be the best approach for this kind of problem, so if anyone has idea what approach to use, shoot.
Thanks!
Echoing the two other; DI is the way to go. Dynamic Proxy is very competent in this respect.
Here is some example code, complete with implementation of all that is required. Normally it's good practice to code against an interface.
I can recommend reading a bit about AOP, here's my thread on it:
Help and Information about Aspect Oriented Programming
(Edit: Becuase you were nice and gave me some points, here's another cool link to a DP tutorial that's really well done: http://kozmic.pl/archive/2009/04/27/castle-dynamic-proxy-tutorial.aspx ;))
Here is example code:
using System;
using System.Collections.Generic;
using Castle.Core;
using Castle.Core.Interceptor;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
using NUnit.Framework;
[TestFixture]
public class LoggingMethodInvocationsTests
{
[Test]
public void CanLogInvocations()
{
var container = new WindsorContainer();
container.Register(Component.For<LoggingInterceptor>().LifeStyle.Singleton);
// log all calls to the interface
container.Register(Component.For<IA>().ImplementedBy<A>().Interceptors(typeof (LoggingInterceptor)));
var a = container.Resolve<IA>();
a.AMethod(3.1415926535); // to interface
Console.WriteLine("End of test");
}
}
public class LoggingInterceptor : IInterceptor, IOnBehalfAware
{
private string _entityName;
public void Intercept(IInvocation invocation)
{
var largs = new List<string>(invocation.Arguments.Length);
for (int i = 0; i < invocation.Arguments.Length; i++)
largs.Add(invocation.Arguments[i].ToString());
var a = largs.Count == 0 ? "[no arguments]" : string.Join(", ", largs.ToArray());
var method = invocation.Method == null ? "[on interface target]" : invocation.Method.Name;
Console.WriteLine(string.Format("{0}.{1} called with arguments {2}", _entityName, method, a));
invocation.Proceed();
Console.WriteLine(string.Format("After invocation. Return value {0}", invocation.ReturnValue));
}
public void SetInterceptedComponentModel(ComponentModel target)
{
if (target != null)
_entityName = target.Implementation.FullName;
}
}
public class A : IA
{
public double AMethod(double a)
{
Console.WriteLine("A method impl");
return a*2;
}
public void SecondMethod(double a)
{
Console.WriteLine(string.Format("Impl: SecondMethod called with {0}", a));
}
}
public interface IA
{
double AMethod(double a);
}
Console output
Examples.A.AMethod called with arguments 3,1415926535
A method impl
After invocation. Return value 6,283185307
End of test
I have use a number of solutions to not quite this problem, but similar things.
1- You could derive a custom proxy from RealProxy and take advantage of the call interceptio provided by the .NET remoting infrastructure. The advantage is that this is super easy, but the limitation is that you need to proxy either an interface and use reflection to invoke the members of your inner class or the class being proxied must inherit from MarshalByRrefObject.
While I hesitate to give a code sample, just because it would not be complete, and I will probably get flamed. But here is a ten minute piece of code just to get you pointed to the right classes etc. Beware, I only handle the IMethodCallMessage so this is not complete but should work as a demo.
class LoggingProxy<T> : RealProxy where T : MarshalByRefObject, new()
{
T _innerObject;
public static T Create()
{
LoggingProxy<T> realProxy = new LoggingProxy<T>();
T transparentProxy = (T)realProxy.GetTransparentProxy();
return transparentProxy;
}
private LoggingProxy() : base(typeof(T))
{
_innerObject = new T();
}
public override IMessage Invoke(IMessage msg)
{
if (msg is IMethodCallMessage)
{
IMethodCallMessage methodCall = msg as IMethodCallMessage;
System.Diagnostics.Debug.WriteLine("Enter: " + methodCall.MethodName);
IMessage returnMessage = RemotingServices.ExecuteMessage(_innerObject, msg as IMethodCallMessage);
System.Diagnostics.Debug.WriteLine("Exit: " + methodCall.MethodName);
return returnMessage;
}
return null;
}
}
This can be used as follows
class MyClass : MarshalByRefObject
{
public int Age
{
get;
set;
}
}
MyClass o = LoggingProxy<MyClass>.Create();
o.Age = 10;
The above will log the call to set_Age on the proxied instance of MyClass.
2- Another alternative, but much more work is to create a proxy class that dynamically generates a type derived from the type you pass in and provides implementations of all the methods and properties in the base type. The generated methods etc. will perform the logging call the base class implementation etc. similar to the RealProxy example. Using VS var type you can probably avoid the need to actually inherit from the type and rather use aggregation for this proxy, that way you will still have intelli-sense support and not need to make all the methods/properties virtual. Sorry no example, this is a little too much for now. But you can look at using CodeDom or better yet Reflection.Emit for the dynamic type building. The dynamic code could do something like that proposed in #tvanfosson's answer.
3- And finally you cpuld use DynamicObject to do much of the above, the disadvantage is that you will not have compile time verification of method calls and no intelli-sense. Again, here is a minimal example.
public class DynamicProxy : System.Dynamic.DynamicObject
{
private object _innerObject;
private Type _innerType;
public DynamicProxy(object inner)
{
if (inner == null) throw new ArgumentNullException("inner");
_innerObject = inner;
_innerType = _innerObject.GetType();
}
public override bool TryInvokeMember(System.Dynamic.InvokeMemberBinder binder, object[] args, out object result)
{
System.Diagnostics.Debug.WriteLine("Enter: ", binder.Name);
try
{
result = _innerType.InvokeMember(
binder.Name,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod,
null, _innerObject, args);
}
catch (MissingMemberException)
{
return base.TryInvokeMember(binder, args, out result);
}
finally
{
System.Diagnostics.Debug.WriteLine("Exit: ", binder.Name);
}
return true;
}
public override bool TryGetMember(System.Dynamic.GetMemberBinder binder, out object result)
{
System.Diagnostics.Debug.WriteLine("Enter: ", binder.Name);
try
{
result = _innerType.InvokeMember(
binder.Name,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty,
null, _innerObject, null);
}
catch (MissingMemberException)
{
return base.TryGetMember(binder, out result);
}
finally
{
System.Diagnostics.Debug.WriteLine("Exit: ", binder.Name);
}
return true;
}
public override bool TrySetMember(System.Dynamic.SetMemberBinder binder, object value)
{
System.Diagnostics.Debug.WriteLine("Enter: ", binder.Name);
try
{
_innerType.InvokeMember(
binder.Name,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty,
null, _innerObject, new object[]{ value });
}
catch (MissingMemberException)
{
return base.TrySetMember(binder, value);
}
finally
{
System.Diagnostics.Debug.WriteLine("Exit: ", binder.Name);
}
return true;
}
public override string ToString()
{
try
{
System.Diagnostics.Debug.WriteLine("Enter: ToString");
return _innerObject.ToString();
}
finally
{
System.Diagnostics.Debug.WriteLine("Exit: ToString");
}
}
}
Which is used something like the following
dynamic o2 = new DynamicProxy(new MyClass());
o.Age = 10;
There are a few option for rolling your own solution, alternatively you can look at some of the pre-backed solutions. Which is probably a better way to go, but this should give you some insight as to how some of the solutions have possibly been implemented.
This may be too heavyweight for your particular use case, but you may want to look into Castle Dynamic Proxy:
Dynamic Proxy
This framework allows you to dynamically create proxies for your classes at runtime, allowing you to intercept all calls and inject whatever logic you want.
The way I would go about it is using dependency injection and passing the logger instance to the class that needs to do the logging. If you had a framework, like MVC, that supports attribute-based filtering, then you could use those as well, though you might be limited in what you could log.
public class LoggedClass
{
private Logger Logger { get; set; }
public LoggerClass( Logger logger )
{
this.Logger = logger;
}
public void A()
{
this.Logger.Info( "A has been called" );
...
}
}
Or in MVC, or a suitable framework that understands attributes and can invoke them before method calls.
[Log]
public ActionResult A()
{
...
}
public class LogAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
... use context to log stuff
}
}
The last alternative, I can think of, which you've already said you don't want to use, is the Decorator pattern. In this case your proxy class and the proxied class would need to implement the same interface and you'd simply wrap the proxied class with the functionality that you wanted. Note that defining the interface -- and extending it when you need to add functionality to the logged class -- protects you from forgetting to extend your proxy to keep it in synch with the logged class. Since it implements the interface it won't compile unless it has all the interface methods.
public interface IDoSomething
{
void A();
void B();
}
public class ToLogClass : IDoSomething
{
public void A() { ... }
public void B() { ... }
}
public class LoggedClass : IDoSomething
{
private IDoSomething Inner { get; set; }
private Logger Logger { get; set; }
public Proxy( IDoSomething inner, Logger logger )
{
this.Inner = inner;
this.Logger = logger;
}
public void A()
{
this.Logger.Info( "A callsed on {0}", this.Inner.GetType().Name );
this.Inner.A();
}
}
Another option is an Aspect-Oriented framework like PostSharp:
http://www.sharpcrafters.com/
This allows you to define attributes that inject code that will be called at certain point during the method call (OnEntry, OnExit, OnException, etc.).
The big downside of this tool is that it requires you to run a post-compilation step against your binaries (the injection is not done dynamically at runtime, but during this post-compile step).
Related
What would be a practical advantage of using generics vs interfaces in this case:
void MyMethod(IFoo f)
{
}
void MyMethod<T>(T f) : where T : IFoo
{
}
I.e. what can you do in MyMethod<T> that you couldn't in the non-generic version? I'm looking for a practical example, I know what the theoretical differences are.
I know that in MyMethod<T>, T will be the concrete type, but nonetheless I will only be able to use it as an IFoo within the body of the method. So what would be a real advantage?
Calling a method through an interface is slower than calling it directly on the concrete type
If the type implementing IFoo is a value type, the non-generic version will box the value of the parameter, and boxing can negatively affect performance (especially if you call this method very often)
If your method returns a value, the generic version can return a T rather than a IFoo, which is convenient if you need to call a method of T on the result
Well, one advantage as mentioned elsewhere, would be the ability to return a specific type of IFoo type if you return a value. But since your question is specifically about void MyMethod(IFoo f), I wanted to give a realistic example of at least one type of situation where using a generic method makes more sense (to me) than the interface. (Yes I spent a bit of time on this, but I wanted to try out some different ideas. :D)
There are two blocks of code, the first is just the generic method itself and some context, the second is the full code for the example, including lots of comments ranging from notes on possible differences between this and an equivalent non-generic implementation, as well as various things I tried while implementing that didn't work, and notes on various choices I made, etc. TL;DR and all that.
Concept
public class FooChains : Dictionary<IFoo, IEnumerable<IFoo>> { }
// to manage our foos and their chains. very important foo chains.
public class FooManager
{
private FooChains myChainList = new FooChains();
// void MyMethod<T>(T f) where T : IFoo
void CopyAndChainFoo<TFoo>(TFoo fromFoo) where TFoo : IFoo
{
TFoo toFoo;
try {
// create a foo from the same type of foo
toFoo = (TFoo)fromFoo.MakeTyped<TFoo>(EFooOpts.ForChain);
}
catch (Exception Ex) {
// hey! that wasn't the same type of foo!
throw new FooChainTypeMismatch(typeof(TFoo), fromFoo, Ex);
}
// a list of a specific type of foos chained to fromFoo
List<TFoo> typedFoos;
if (!myChainList.Keys.Contains(fromFoo))
{
// no foos there! make a list and connect them to fromFoo
typedChain = new List<TFoo>();
myChainList.Add(fromFoo, (IEnumerable<IFoo>)typedChain);
}
else
// oh good, the chain exists, phew!
typedChain = (List<TFoo>)myChainList[fromFoo];
// add the new foo to the connected chain of foos
typedChain.Add(toFoo);
// and we're done!
}
}
Gory Details
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace IFooedYouOnce
{
// IFoo
//
// It's personality is so magnetic, it's erased hard drives.
// It can debug other code... by actually debugging other code.
// It can speak Haskell... in C.
//
// It *is* the most interesting interface in the world.
public interface IFoo
{
// didn't end up using this but it's still there because some
// of the supporting derived classes look silly without it.
bool CanChain { get; }
string FooIdentifier { get; }
// would like to place constraints on this in derived methods
// to ensure type safety, but had to use exceptions instead.
// Liskov yada yada yada...
IFoo MakeTyped<TFoo>(EFooOpts fooOpts);
}
// using IEnumerable<IFoo> here to take advantage of covariance;
// we can have lists of derived foos and just cast back and
// forth for adding or if we need to use the derived interfaces.
// made it into a separate class because probably there will be
// specific operations you can do on the chain collection as a
// whole so this way there's a spot for it instead of, say,
// implementing it all in the FooManager
public class FooChains : Dictionary<IFoo, IEnumerable<IFoo>> { }
// manages the foos. very highly important foos.
public class FooManager
{
private FooChains myChainList = new FooChains();
// would perhaps add a new() constraint here to make the
// creation a little easier; could drop the whole MakeTyped
// method. but was trying to stick with the interface from
// the question.
void CopyAndChainFoo<TFoo>(TFoo fromFoo) where TFoo : IFoo
// void MyMethod<T>(T f) where T : IFoo
{
TFoo toFoo;
// without generics, I would probably create a factory
// method on one of the base classes that could return
// any type, and pass in a type. other ways are possible,
// for instance, having a method which took two IFoos,
// fromFoo and toFoo, and handling the Copy elsewhere.
// could have bypassed this try/catch altogether because
// MakeTyped functions throw if the types are not equal,
// but wanted to make it explicit here. also, this gives
// a more descriptive error which, in general, I prefer
try
{
// MakeTyped<TFoo> was a solution to allowing each TFoo
// to be in charge of creating its own objects
toFoo =
(TFoo)fromFoo.MakeTyped<TFoo>(EFooOpts.ForChain);
}
catch (Exception Ex) {
// tried to eliminate the need for this try/catch, but
// didn't manage. can't constrain the derived classes'
// MakeTyped functions on their own types, and didn't
// want to change the constraints to new() as mentioned
throw
new FooChainTypeMismatch(typeof(TFoo), fromFoo, Ex);
}
// a list of specific type foos to hold the chain
List<TFoo> typedFoos;
if (!myChainList.Keys.Contains(fromFoo))
{
// we just create a new one and link it to the fromFoo
// if none already exists
typedFoos = new List<TFoo>();
myChainList.Add(fromFoo, (IEnumerable<IFoo>)typedFoos);
}
else
// otherwise get the existing one; we are using the
// IEnumerable to hold actual List<TFoos> so we can just
// cast here.
typedFoos = (List<TFoo>)myChainList[fromFoo];
// add it in!
typedFoos.Add(toFoo);
}
}
[Flags]
public enum EFooOpts
{
ForChain = 0x01,
FullDup = 0x02,
RawCopy = 0x04,
Specialize = 0x08
}
// base class, originally so we could have the chainable/
// non chainable distinction but that turned out to be
// fairly pointless since I didn't use it. so, just left
// it like it was anyway so I didn't have to rework all
// the classes again.
public abstract class FooBase : IFoo
{
public string FooIdentifier { get; protected set; }
public abstract bool CanChain { get; }
public abstract IFoo MakeTyped<TFoo>(EFooOpts parOpts);
}
public abstract class NonChainableFoo : FooBase
{
public override bool CanChain { get { return false; } }
}
public abstract class ChainableFoo : FooBase
{
public override bool CanChain { get { return true; } }
}
// not much more interesting to see here; the MakeTyped would
// have been nicer not to exist, but that would have required
// a new() constraint on the chains function.
//
// or would have added "where TFoo : MarkIFoo" type constraint
// on the derived classes' implementation of it, but that's not
// allowed due to the fact that the constraints have to derive
// from the base method, which had to exist on the abstract
// classes to implement IFoo.
public class MarkIFoo : NonChainableFoo
{
public MarkIFoo()
{ FooIdentifier = "MI_-" + Guid.NewGuid().ToString(); }
public override IFoo MakeTyped<TFoo>(EFooOpts fooOpts)
{
if (typeof(TFoo) != typeof(MarkIFoo))
throw new FooCopyTypeMismatch(typeof(TFoo), this, null);
return new MarkIFoo(this, fooOpts);
}
private MarkIFoo(MarkIFoo fromFoo, EFooOpts parOpts) :
this() { /* copy MarkOne foo here */ }
}
public class MarkIIFoo : ChainableFoo
{
public MarkIIFoo()
{ FooIdentifier = "MII-" + Guid.NewGuid().ToString(); }
public override IFoo MakeTyped<TFoo>(EFooOpts fooOpts)
{
if (typeof(TFoo) != typeof(MarkIIFoo))
throw new FooCopyTypeMismatch(typeof(TFoo), this, null);
return new MarkIIFoo(this, fooOpts);
}
private MarkIIFoo(MarkIIFoo fromFoo, EFooOpts parOpts) :
this() { /* copy MarkTwo foo here */ }
}
// yep, really, that's about all.
public class FooException : Exception
{
public Tuple<string, object>[] itemDetail { get; private set; }
public FooException(
string message, Exception inner,
params Tuple<string, object>[] parItemDetail
) : base(message, inner)
{
itemDetail = parItemDetail;
}
public FooException(
string msg, object srcItem, object destType, Exception inner
) : this(msg, inner,
Tuple.Create("src", srcItem), Tuple.Create("dtype", destType)
) { }
}
public class FooCopyTypeMismatch : FooException
{
public FooCopyTypeMismatch(
Type reqDestType, IFoo reqFromFoo, Exception inner
) : base("copy type mismatch", reqFromFoo, reqDestType, inner)
{ }
}
public class FooChainTypeMismatch : FooException
{
public FooChainTypeMismatch(
Type reqDestType, IFoo reqFromFoo, Exception inner
) : base("chain type mismatch", reqFromFoo, reqDestType, inner)
{ }
}
}
// I(Foo) shot J.R.!
Doing things like these is easier:
void MyMethod<T>(T f) where T : IFoo, new() {
var t1 = new T();
var t2 = default(T);
// Etc...
}
Also, as you introduce more interfaces, generics may be more "gentle" to callers. For example, you can inherit a class from 2 interfaces and pass it directly, like this...
interface IFoo {
}
interface IBar {
}
class FooBar : IFoo, IBar {
}
void MyMethod<T>(T f) where T : IFoo, IBar {
}
void Test() {
FooBar fb = new FooBar();
MyMethod(fb);
}
...while "interface-only" method would require an "intermediary" interface (IFooBar)...
interface IFoo {
}
interface IBar {
}
interface IFooBar : IFoo, IBar {
}
class FooBar : IFooBar {
}
void MyMethod(IFooBar f) {
}
void Test() {
FooBar fb = new FooBar();
MyMethod(fb);
}
2 years later I found a very simple and useful case. Consider this common pattern:
class MyClass : IDisposable {
public void Dispose() {
if (m_field1 != null) {
m_field1.Dispose();
m_field1 = null;
}
if (m_field2 != null) {
m_field2.Dispose();
m_field2 = null;
}
// etc
}
}
I've always wanted to write a helper method to avoid having to write all this boilerplate for every field:
class MyClass : IDisposable {
static void IfNotNullDispose(ref IDisposable disposable) {
if (disposable != null) {
disposable.Dispose();
disposable = null;
}
}
public void Dispose() {
IfNotNullDispose(ref m_field1);
IfNotNullDispose(ref m_field2);
// etc
}
}
Unfortunately this is illegal in C# because you cannot use an interface for ref parameters, you must use the concrete type you'll pass in and nothing else. So you'd have to write a different method for every single type of field you want to dispose. Oh wait that's exactly what generics do for you:
static void IfNotNullDispose<T>(ref T disposable) where T: class, IDisposable {
if (disposable != null) {
disposable.Dispose();
disposable = null;
}
}
Now everything works as intended!
In this particular case, there is no benefit. In general you wouldn't specify this at a method level, but at a class level. E.g.,
public interface IFoo {
void DoSomethingImportant();
}
public class MyContainer<T> where T : IFoo {
public void Add(T something){
something.DoSomethingImportant();
AddThisThing(something);
}
public T Get() {
T theThing = GetSomeKindOfThing();
return theThing;
}
}
Notice that we require T to implement IFoo because of the Add method where we need to call the DoSomethingImportantMethod implemented by IFoo.
But notice in the Get method that we will return the T provided by end user of this class instead of a plain old IFoo, which alleviates the need for the developer to always cast to their actual concrete T.
Example:
public class Bar : IFoo{
//....
}
MyContainer<Bar> m = new MyContainer<Bar>();
//stuff happens here
Bar b = m.Get();
Note that if I was just returning an IFoo, then I would have to do this at the last line instead:
Bar b = (Bar) m.Get();
The interface method will supply you an f of type IFoo, whereas the generic version will supply you a type T with the constraint that T has to implement IFoo.
The second method would allow you to have some kind of lookup depending on T, as you have a concrete type to work with.
referring to the benchmark reported above
#Branko, calling a method through an interface is actually slower than >a "normal" virtual method call... Here's a simple benchmark: >pastebin.com/jx3W5zWb – Thomas Levesque Aug 29 '11 at 0:33
running the code in Visual Studio 2015 the result are roughly equivalent between Direct call and Through interface:
Direct call: 90,51 millisec; 112,49 millisec; 81,22 millisec
Through interface: 92,85 millisec;90,14 millisec; 88,56 millisec
the code used to benchmark (from http://pastebin.com/jx3W5zWb ) is:
using System;
using System.Diagnostics;
namespace test
{
class MainApp
{
static void Main()
{
Foo f = new Foo();
IFoo f2 = f;
// JIT warm-up
f.Bar();
f2.Bar();
int N = 10000000;
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < N; i++)
{
f2.Bar();
}
sw.Stop();
Console.WriteLine("Through interface: {0:F2}", sw.Elapsed.TotalMilliseconds);
sw.Reset();
sw.Start();
for (int i = 0; i < N; i++)
{
f.Bar();
}
sw.Stop();
Console.WriteLine("Direct call: {0:F2}", sw.Elapsed.TotalMilliseconds);
Console.Read();
}
interface IFoo
{
void Bar();
}
class Foo : IFoo
{
public virtual void Bar()
{
}
}
}
}
The generic version allows you to use any type as T - which you for some reason restricted back by using the where clause, whereas your non-generic version supports only something implementing IFoo.
Another (maybe better) question is - are these two options equivalent?
What would be a practical advantage of using generics vs interfaces in this case:
void MyMethod(IFoo f)
{
}
void MyMethod<T>(T f) : where T : IFoo
{
}
I.e. what can you do in MyMethod<T> that you couldn't in the non-generic version? I'm looking for a practical example, I know what the theoretical differences are.
I know that in MyMethod<T>, T will be the concrete type, but nonetheless I will only be able to use it as an IFoo within the body of the method. So what would be a real advantage?
Calling a method through an interface is slower than calling it directly on the concrete type
If the type implementing IFoo is a value type, the non-generic version will box the value of the parameter, and boxing can negatively affect performance (especially if you call this method very often)
If your method returns a value, the generic version can return a T rather than a IFoo, which is convenient if you need to call a method of T on the result
Well, one advantage as mentioned elsewhere, would be the ability to return a specific type of IFoo type if you return a value. But since your question is specifically about void MyMethod(IFoo f), I wanted to give a realistic example of at least one type of situation where using a generic method makes more sense (to me) than the interface. (Yes I spent a bit of time on this, but I wanted to try out some different ideas. :D)
There are two blocks of code, the first is just the generic method itself and some context, the second is the full code for the example, including lots of comments ranging from notes on possible differences between this and an equivalent non-generic implementation, as well as various things I tried while implementing that didn't work, and notes on various choices I made, etc. TL;DR and all that.
Concept
public class FooChains : Dictionary<IFoo, IEnumerable<IFoo>> { }
// to manage our foos and their chains. very important foo chains.
public class FooManager
{
private FooChains myChainList = new FooChains();
// void MyMethod<T>(T f) where T : IFoo
void CopyAndChainFoo<TFoo>(TFoo fromFoo) where TFoo : IFoo
{
TFoo toFoo;
try {
// create a foo from the same type of foo
toFoo = (TFoo)fromFoo.MakeTyped<TFoo>(EFooOpts.ForChain);
}
catch (Exception Ex) {
// hey! that wasn't the same type of foo!
throw new FooChainTypeMismatch(typeof(TFoo), fromFoo, Ex);
}
// a list of a specific type of foos chained to fromFoo
List<TFoo> typedFoos;
if (!myChainList.Keys.Contains(fromFoo))
{
// no foos there! make a list and connect them to fromFoo
typedChain = new List<TFoo>();
myChainList.Add(fromFoo, (IEnumerable<IFoo>)typedChain);
}
else
// oh good, the chain exists, phew!
typedChain = (List<TFoo>)myChainList[fromFoo];
// add the new foo to the connected chain of foos
typedChain.Add(toFoo);
// and we're done!
}
}
Gory Details
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace IFooedYouOnce
{
// IFoo
//
// It's personality is so magnetic, it's erased hard drives.
// It can debug other code... by actually debugging other code.
// It can speak Haskell... in C.
//
// It *is* the most interesting interface in the world.
public interface IFoo
{
// didn't end up using this but it's still there because some
// of the supporting derived classes look silly without it.
bool CanChain { get; }
string FooIdentifier { get; }
// would like to place constraints on this in derived methods
// to ensure type safety, but had to use exceptions instead.
// Liskov yada yada yada...
IFoo MakeTyped<TFoo>(EFooOpts fooOpts);
}
// using IEnumerable<IFoo> here to take advantage of covariance;
// we can have lists of derived foos and just cast back and
// forth for adding or if we need to use the derived interfaces.
// made it into a separate class because probably there will be
// specific operations you can do on the chain collection as a
// whole so this way there's a spot for it instead of, say,
// implementing it all in the FooManager
public class FooChains : Dictionary<IFoo, IEnumerable<IFoo>> { }
// manages the foos. very highly important foos.
public class FooManager
{
private FooChains myChainList = new FooChains();
// would perhaps add a new() constraint here to make the
// creation a little easier; could drop the whole MakeTyped
// method. but was trying to stick with the interface from
// the question.
void CopyAndChainFoo<TFoo>(TFoo fromFoo) where TFoo : IFoo
// void MyMethod<T>(T f) where T : IFoo
{
TFoo toFoo;
// without generics, I would probably create a factory
// method on one of the base classes that could return
// any type, and pass in a type. other ways are possible,
// for instance, having a method which took two IFoos,
// fromFoo and toFoo, and handling the Copy elsewhere.
// could have bypassed this try/catch altogether because
// MakeTyped functions throw if the types are not equal,
// but wanted to make it explicit here. also, this gives
// a more descriptive error which, in general, I prefer
try
{
// MakeTyped<TFoo> was a solution to allowing each TFoo
// to be in charge of creating its own objects
toFoo =
(TFoo)fromFoo.MakeTyped<TFoo>(EFooOpts.ForChain);
}
catch (Exception Ex) {
// tried to eliminate the need for this try/catch, but
// didn't manage. can't constrain the derived classes'
// MakeTyped functions on their own types, and didn't
// want to change the constraints to new() as mentioned
throw
new FooChainTypeMismatch(typeof(TFoo), fromFoo, Ex);
}
// a list of specific type foos to hold the chain
List<TFoo> typedFoos;
if (!myChainList.Keys.Contains(fromFoo))
{
// we just create a new one and link it to the fromFoo
// if none already exists
typedFoos = new List<TFoo>();
myChainList.Add(fromFoo, (IEnumerable<IFoo>)typedFoos);
}
else
// otherwise get the existing one; we are using the
// IEnumerable to hold actual List<TFoos> so we can just
// cast here.
typedFoos = (List<TFoo>)myChainList[fromFoo];
// add it in!
typedFoos.Add(toFoo);
}
}
[Flags]
public enum EFooOpts
{
ForChain = 0x01,
FullDup = 0x02,
RawCopy = 0x04,
Specialize = 0x08
}
// base class, originally so we could have the chainable/
// non chainable distinction but that turned out to be
// fairly pointless since I didn't use it. so, just left
// it like it was anyway so I didn't have to rework all
// the classes again.
public abstract class FooBase : IFoo
{
public string FooIdentifier { get; protected set; }
public abstract bool CanChain { get; }
public abstract IFoo MakeTyped<TFoo>(EFooOpts parOpts);
}
public abstract class NonChainableFoo : FooBase
{
public override bool CanChain { get { return false; } }
}
public abstract class ChainableFoo : FooBase
{
public override bool CanChain { get { return true; } }
}
// not much more interesting to see here; the MakeTyped would
// have been nicer not to exist, but that would have required
// a new() constraint on the chains function.
//
// or would have added "where TFoo : MarkIFoo" type constraint
// on the derived classes' implementation of it, but that's not
// allowed due to the fact that the constraints have to derive
// from the base method, which had to exist on the abstract
// classes to implement IFoo.
public class MarkIFoo : NonChainableFoo
{
public MarkIFoo()
{ FooIdentifier = "MI_-" + Guid.NewGuid().ToString(); }
public override IFoo MakeTyped<TFoo>(EFooOpts fooOpts)
{
if (typeof(TFoo) != typeof(MarkIFoo))
throw new FooCopyTypeMismatch(typeof(TFoo), this, null);
return new MarkIFoo(this, fooOpts);
}
private MarkIFoo(MarkIFoo fromFoo, EFooOpts parOpts) :
this() { /* copy MarkOne foo here */ }
}
public class MarkIIFoo : ChainableFoo
{
public MarkIIFoo()
{ FooIdentifier = "MII-" + Guid.NewGuid().ToString(); }
public override IFoo MakeTyped<TFoo>(EFooOpts fooOpts)
{
if (typeof(TFoo) != typeof(MarkIIFoo))
throw new FooCopyTypeMismatch(typeof(TFoo), this, null);
return new MarkIIFoo(this, fooOpts);
}
private MarkIIFoo(MarkIIFoo fromFoo, EFooOpts parOpts) :
this() { /* copy MarkTwo foo here */ }
}
// yep, really, that's about all.
public class FooException : Exception
{
public Tuple<string, object>[] itemDetail { get; private set; }
public FooException(
string message, Exception inner,
params Tuple<string, object>[] parItemDetail
) : base(message, inner)
{
itemDetail = parItemDetail;
}
public FooException(
string msg, object srcItem, object destType, Exception inner
) : this(msg, inner,
Tuple.Create("src", srcItem), Tuple.Create("dtype", destType)
) { }
}
public class FooCopyTypeMismatch : FooException
{
public FooCopyTypeMismatch(
Type reqDestType, IFoo reqFromFoo, Exception inner
) : base("copy type mismatch", reqFromFoo, reqDestType, inner)
{ }
}
public class FooChainTypeMismatch : FooException
{
public FooChainTypeMismatch(
Type reqDestType, IFoo reqFromFoo, Exception inner
) : base("chain type mismatch", reqFromFoo, reqDestType, inner)
{ }
}
}
// I(Foo) shot J.R.!
Doing things like these is easier:
void MyMethod<T>(T f) where T : IFoo, new() {
var t1 = new T();
var t2 = default(T);
// Etc...
}
Also, as you introduce more interfaces, generics may be more "gentle" to callers. For example, you can inherit a class from 2 interfaces and pass it directly, like this...
interface IFoo {
}
interface IBar {
}
class FooBar : IFoo, IBar {
}
void MyMethod<T>(T f) where T : IFoo, IBar {
}
void Test() {
FooBar fb = new FooBar();
MyMethod(fb);
}
...while "interface-only" method would require an "intermediary" interface (IFooBar)...
interface IFoo {
}
interface IBar {
}
interface IFooBar : IFoo, IBar {
}
class FooBar : IFooBar {
}
void MyMethod(IFooBar f) {
}
void Test() {
FooBar fb = new FooBar();
MyMethod(fb);
}
2 years later I found a very simple and useful case. Consider this common pattern:
class MyClass : IDisposable {
public void Dispose() {
if (m_field1 != null) {
m_field1.Dispose();
m_field1 = null;
}
if (m_field2 != null) {
m_field2.Dispose();
m_field2 = null;
}
// etc
}
}
I've always wanted to write a helper method to avoid having to write all this boilerplate for every field:
class MyClass : IDisposable {
static void IfNotNullDispose(ref IDisposable disposable) {
if (disposable != null) {
disposable.Dispose();
disposable = null;
}
}
public void Dispose() {
IfNotNullDispose(ref m_field1);
IfNotNullDispose(ref m_field2);
// etc
}
}
Unfortunately this is illegal in C# because you cannot use an interface for ref parameters, you must use the concrete type you'll pass in and nothing else. So you'd have to write a different method for every single type of field you want to dispose. Oh wait that's exactly what generics do for you:
static void IfNotNullDispose<T>(ref T disposable) where T: class, IDisposable {
if (disposable != null) {
disposable.Dispose();
disposable = null;
}
}
Now everything works as intended!
In this particular case, there is no benefit. In general you wouldn't specify this at a method level, but at a class level. E.g.,
public interface IFoo {
void DoSomethingImportant();
}
public class MyContainer<T> where T : IFoo {
public void Add(T something){
something.DoSomethingImportant();
AddThisThing(something);
}
public T Get() {
T theThing = GetSomeKindOfThing();
return theThing;
}
}
Notice that we require T to implement IFoo because of the Add method where we need to call the DoSomethingImportantMethod implemented by IFoo.
But notice in the Get method that we will return the T provided by end user of this class instead of a plain old IFoo, which alleviates the need for the developer to always cast to their actual concrete T.
Example:
public class Bar : IFoo{
//....
}
MyContainer<Bar> m = new MyContainer<Bar>();
//stuff happens here
Bar b = m.Get();
Note that if I was just returning an IFoo, then I would have to do this at the last line instead:
Bar b = (Bar) m.Get();
The interface method will supply you an f of type IFoo, whereas the generic version will supply you a type T with the constraint that T has to implement IFoo.
The second method would allow you to have some kind of lookup depending on T, as you have a concrete type to work with.
referring to the benchmark reported above
#Branko, calling a method through an interface is actually slower than >a "normal" virtual method call... Here's a simple benchmark: >pastebin.com/jx3W5zWb – Thomas Levesque Aug 29 '11 at 0:33
running the code in Visual Studio 2015 the result are roughly equivalent between Direct call and Through interface:
Direct call: 90,51 millisec; 112,49 millisec; 81,22 millisec
Through interface: 92,85 millisec;90,14 millisec; 88,56 millisec
the code used to benchmark (from http://pastebin.com/jx3W5zWb ) is:
using System;
using System.Diagnostics;
namespace test
{
class MainApp
{
static void Main()
{
Foo f = new Foo();
IFoo f2 = f;
// JIT warm-up
f.Bar();
f2.Bar();
int N = 10000000;
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < N; i++)
{
f2.Bar();
}
sw.Stop();
Console.WriteLine("Through interface: {0:F2}", sw.Elapsed.TotalMilliseconds);
sw.Reset();
sw.Start();
for (int i = 0; i < N; i++)
{
f.Bar();
}
sw.Stop();
Console.WriteLine("Direct call: {0:F2}", sw.Elapsed.TotalMilliseconds);
Console.Read();
}
interface IFoo
{
void Bar();
}
class Foo : IFoo
{
public virtual void Bar()
{
}
}
}
}
The generic version allows you to use any type as T - which you for some reason restricted back by using the where clause, whereas your non-generic version supports only something implementing IFoo.
Another (maybe better) question is - are these two options equivalent?
In C#, is it possible to write something like this:
public class MyClass<T> : T
where T : class, new()
{
}
I know that the above implementation does not compile, but what I am actually trying to achive is implementing some kind of generic wrapper to an unknown type, so that an client can call the wrapper just as he would call the type, provided by the parameter T, instead of calling it using something like wrapper.Instance.SomeMember().
Thanks in advance!
This isn't possible.
In my opinion, I don't think that a wrapper should be implemented using inheritance.
For example, let's say we've an Engine class and you need to implement a FerrariEngine. And you have a Car class.
You're saying that Car should inherit FerrariEngine. It looks terrible for me!
At the end of the day, you're looking to do something like dependency injection using inheritance and, again, this isn't the right path.
My suggestion is don't try to make your life easier: decide an architecture based on rational points.
UPDATE
The OP said in some comment:
I want to make this class to manage instances of objects of type T, so
that the client does not need to take care of when the instances need
to be created.
You don't need to make strange things to get what you want:
public interface IEngine
{
void Start();
}
public sealed class FerrariEngine : IEngine
{
public FerrariEngine()
{
Start();
}
public void Start()
{
}
}
public abstract class Car<TEngine> where TEngine: IEngine, new()
{
public Car()
{
_engine = new Lazy<TEngine>(() => new TEngine());
}
private readonly Lazy<TEngine> _engine;
public TEngine Engine
{
get { return _engine.Value; }
}
}
public class FerrariCar : Car<FerrariEngine>
{
}
Finally, if we create an instance of FerrariCar:
Car<FerrariEngine> myFerrari = new FerrariCar();
The engine will be instantiated and started, without developer intervention!
Check how Lazy<T> and basic generic constraints make the job ;)
In summary:
Using Lazy<T> the engine will be instantiated only when some access the Engine property.
Once the lazy-loaded engine is instantiated, since FerrariEngine implements a parameterless constructor calling Start() itself, it will start the engine.
I believe that this sample illustrates you how you can get what you're looking for and using C# "as is"!
You could have a look at DynamicObject and do something like this:
class Foo<T> : DynamicObject
{
private T _instance;
public Foo(T instance)
{
_instance = instance;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
var member = typeof(T).GetProperty(binder.Name);
if (_instance != null &&
member.CanWrite &&
value.GetType() == member.PropertyType)
{
member.SetValue(_instance, value, null);
return true;
}
return false;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
var member = typeof(T).GetProperty(binder.Name);
if (_instance != null &&
member.CanRead)
{
result = member.GetValue(_instance, null);
return true;
}
result = null;
return false;
}
}
class Bar
{
public int SomeProperty { get; set; }
}
class Program
{
static void Main(string[] args)
{
var bar = new Bar();
dynamic thing = new Foo<Bar>(bar);
thing.SomeProperty = 42;
Console.WriteLine(thing.SomeProperty);
Console.ReadLine();
}
}
Suppose I have assembly that declares internal interface IInternalInterface. I have no access to code of this assembly and I can't change it.
How can I create my own implementation of IInternalInterface?
Why I need this: the assembly contains the class with list of IInternalInterface implementers and my goal is to add my own implementation there.
It is possible using remoting proxy.
Note that my answer is just a quick sketch and might need to be improved further.
internal interface IInternalInterface {
void SayHello();
}
// --------------------------------------------------------------
// in another assembly
public class ImplementationProxy : RealProxy, IRemotingTypeInfo {
private readonly MethodInfo method;
public ImplementationProxy(MethodInfo method)
: base(typeof(ContextBoundObject))
{
this.method = method;
}
public override IMessage Invoke(IMessage msg) {
if (!(msg is IMethodCallMessage))
throw new NotSupportedException();
var call = (IMethodCallMessage)msg;
if (call.MethodBase != this.method)
throw new NotSupportedException();
Console.WriteLine("Hi from internals!");
return new ReturnMessage(null, null, 0, call.LogicalCallContext, call);
}
public bool CanCastTo(Type fromType, object o)
{
return fromType == method.DeclaringType;
}
public string TypeName
{
get { return this.GetType().Name; }
set { }
}
}
How can I to create my own implementation of IInternalInterface?
Simple answer: you can't. If the authors of the assembly decided to mark this interface with internal it means that they didn't want code from other assemblies to use this interface.
I will extend the answer from #AndreyShchekin as it was really useful but missed some bits:
public class Program
{
public static void Main()
{
var internalType = typeof(PublicTypeInAnotherAssembly).Assembly.GetType("Full name of internal type: System.Internals.IInterface");
var result = new InterfaceImplementer(internalType, InterfaceCalled).GetTransparentProxy();
}
static object InterfaceCalled(MethodInfo info)
{
// Implement logic.
Console.WriteLine($"{info.Name}: Did someone call an internal method?");
// Return value matching info.ReturnType or null if void.
return null;
}
}
public class InterfaceImplementer : RealProxy, IRemotingTypeInfo
{
readonly Type _type;
readonly Func<MethodInfo, object> _callback;
public InterfaceImplementer(Type type, Func<MethodInfo, object> callback) : base(type)
{
_callback = callback;
_type = type;
}
public override IMessage Invoke(IMessage msg)
{
var call = msg as IMethodCallMessage;
if (call == null)
throw new NotSupportedException();
var method = (MethodInfo)call.MethodBase;
return new ReturnMessage(_callback(method), null, 0, call.LogicalCallContext, call);
}
public bool CanCastTo(Type fromType, object o) => fromType == _type;
public string TypeName { get; set; }
}
Now result is assignable to the internal interface. To verify it, we can do this in the assembly containing the internal interface:
public class PublicTypeInAnotherAssembly
{
public void Test(object proxy)
{
var internalInterface = (IInternalInterface)proxy;
internalInterface.MethodOnInterface();
}
}
Or assign it with reflection if we don't have access.
You could also use assembly version redirection or type redirection to "move" the interface declaration to an assembly under your control and make your implementation public.
But as Darin said, be sure to double-think about this approach. There may be an intended way to extend the library functionality that would be much cleaner...
I am afraid this is impossible. Even if you manage to make a class that implements that interface using Reflection.Emit, you won't be able to use it because you will get a ReflectionTypeLoadException: Type is attempting to implement an inaccessible interface
You could add [InternalsVisibleTo()] attribute, but as far as you have no access to source code, you can't implement this interface at compile time
From the other hand, you can do it at run time. For this you should use runtime code generation (also known as Reflection.Emit) and fetch the interface type with BindingFlags.NonPublic. You can read more about it here.
UPDATED:
As mentioned in comments below, it is impossible to inherit from a non-public interface. So unfortunately you have no solutions.
I have a class that implements two interfaces, and I want to apply interception to the class's methods.
I'm following the advice in Unity Register two interfaces as one singleton, but I'm surprised by the results. In a nutshell, it seems that my CallHandler is called twice. The shortest example I have is this:
public interface I1
{
void Method1();
}
public interface I2
{
void Method2();
}
public class C : I1, I2
{
[Log]
public void Method1() {}
public void Method2() {}
}
public class LogAttribute : HandlerAttribute
{
public override ICallHandler CreateHandler(IUnityContainer container)
{
return new LogCallHandler();
}
}
public class LogCallHandler : ICallHandler
{
public IMethodReturn Invoke(
IMethodInvocation input, GetNextHandlerDelegate getNext)
{
Console.WriteLine("Entering " + input.MethodBase.Name);
var methodReturn = getNext().Invoke(input, getNext);
Console.WriteLine("Leaving " + input.MethodBase.Name);
return methodReturn;
}
public int Order { get; set; }
}
void Test()
{
IUnityContainer container = new UnityContainer();
container.AddNewExtension<Interception>();
container.RegisterType<C>(new ContainerControlledLifetimeManager());
container.RegisterType<I1, C>(
new Interceptor<TransparentProxyInterceptor>(),
new InterceptionBehavior<PolicyInjectionBehavior>());
container.RegisterType<I2, C>(
new Interceptor<TransparentProxyInterceptor>(),
new InterceptionBehavior<PolicyInjectionBehavior>());
container.Resolve<I1>().Method1();
}
Which gives this output:
Entering Method1
Entering Method1
Leaving Method1
Leaving Method1
Removing the "container.RegisterType I2, C" line makes the log appear only once. Adding a third interface, I3, which is similar to I2, causes the log to appear three times.
I would have expected the Log to be called only once. I can probably achieve this by having the LogCallHandler detect if it's being invoked from another LogCallHandler, but this seems inelegant.
Originally I wanted to apply the interception behavior to C rather than to I1 and I2 separately, but this requires C to inherit from MarshalByRefObject which is a constraint I'm not yet willing to impose.
Is there an alternative way?
The problem is that you are applying the transparent proxy to each interface. Instead, if you apply it to the concrete class you get only one proxy. Also, you don't need to make it a singleton unless you want the instance to be shared.
I ran this configuration in a test console project and got the desired result. Kudos for including a working snippet that isolated your problem!
var container = new UnityContainer()
.AddNewExtension<Interception>()
.RegisterType<I1, C>()
.RegisterType<I2, C>()
.RegisterType<C>(
new ContainerControlledLifetimeManager(),
new Interceptor<TransparentProxyInterceptor>(),
new InterceptionBehavior<PolicyInjectionBehavior>()
);
As it turns out, a small modification of my original snippet gives a solution:
public interface I1
{
void Method1();
}
public interface I2
{
void Method2();
}
public class C : I1, I2
{
public int Data = 0;
[Log]
public void Method1() { Console.WriteLine("Method1 " + Data); Data = 1; }
[Log]
public void Method2() { Console.WriteLine("Method2 " + Data); Data = 2; }
}
public class LogAttribute : HandlerAttribute
{
public override ICallHandler CreateHandler(IUnityContainer container)
{
return new LogCallHandler();
}
}
public class LogCallHandler : ICallHandler
{
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
Console.WriteLine("Entering " + input.MethodBase.Name);
var methodReturn = getNext().Invoke(input, getNext);
Console.WriteLine("Leaving " + input.MethodBase.Name);
return methodReturn;
}
public int Order { get; set; }
}
void Test()
{
IUnityContainer container = new UnityContainer();
container.AddNewExtension<Interception>();
container.RegisterType<C>(new ContainerControlledLifetimeManager());
container.RegisterType<I1, C>();
container.RegisterType<I2, C>();
container.Configure<Interception>().SetInterceptorFor<I1>(new TransparentProxyInterceptor());
container.Configure<Interception>().SetInterceptorFor<I2>(new TransparentProxyInterceptor());
container.Resolve<I1>().Method1();
container.Resolve<I2>().Method2();
container.Resolve<C>().Method2();
}
The only difference is that I set the interception for I1 and I2 outside the call to RegisterType. The output of the above is:
Entering Method1
Method1 0
Leaving Method1
Entering Method2
Method2 1
Leaving Method2
Method2 2
Which gives me the following:
I intercept C's implementation of both I1 and I2.
There is only a single instance of C (as evidenced by the modification to the Data member).
I can reach the single instance of C (i.e. container.Resolve<C>() works, albeit without interception).
My use case here is unit-tests: my code relies on interception for some of its functionality (specifically, transaction management). C is a mock object that I provide to my tested class, and it implements two interfaces that the tested class needs. When the unit-test runs, I want to access the mock object to verify stuff on it.
The downside to the above solution is that I can only apply PolicyInjectionBehavior here (in fact, the code above doesn't specify any InterceptionBehavior: when using container.Configure<Interception>, the PolicyInjectionBehavior is automatically used by Unity, as far as I could tell. For my use case, it is acceptable.
I have to admit that I'm surprised that setting up interception during RegisterType gives different results than configuring it separately. If anyone can explain this, I'd be happy to understand why that is.