Created
April 26, 2010 15:15
-
-
Save statianzo/379452 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Dynamic; | |
using System.Linq; | |
using System.Reflection; | |
using Autofac; | |
//Proof of Concept for a Service Agent implementation using dynamic | |
namespace ActionContainer | |
{ | |
internal class Program | |
{ | |
private static void Main(string[] args) | |
{ | |
var builder = new ContainerBuilder(); | |
builder.RegisterType<ServiceAgent>().As<dynamic>(); | |
builder.RegisterAssemblyTypes(typeof (Program).Assembly) | |
.AssignableTo<IDependOnSomething>() | |
.WithProperty("ServiceAgent", new ServiceAgent()) | |
.AsImplementedInterfaces(); | |
IContainer container = builder.Build(); | |
var depender = container.Resolve<IDependOnSomething>(); | |
depender.DoYourThing(); | |
} | |
} | |
public class Needy : IDependOnSomething | |
{ | |
public dynamic ServiceAgent { get; set; } | |
public void DoYourThing() | |
{ | |
//Void call | |
ServiceAgent.VoidMethod(23); | |
//Call that returns an integer | |
int i = ServiceAgent.GiveMeAnInt(40); | |
Console.WriteLine("{0} - {1}", i, i.GetType()); | |
//Call that returns a string | |
string s = ServiceAgent.WhatAboutAString(938); | |
Console.WriteLine("{0} - {1}", s, s.GetType()); | |
//Missing method | |
bool q = ServiceAgent.CanYouBoolMe("Hello"); | |
} | |
} | |
public interface IDependOnSomething | |
{ | |
dynamic ServiceAgent { get; set; } | |
void DoYourThing(); | |
} | |
internal class ServiceAgent : DynamicObject | |
{ | |
private IList<MethodInfo> PossibleMethods { get; set; } | |
private object[] Args { get; set; } | |
public override bool TryConvert(ConvertBinder binder, out object result) | |
{ | |
MethodInfo method = PossibleMethods.FirstOrDefault(x => x.ReturnType == binder.ReturnType); | |
if (method == null) | |
throw new MissingMethodException("No method matching provided signature found"); | |
result = method.Invoke(null, Args); | |
return true; | |
} | |
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) | |
{ | |
var meth1 = new Func<int, string>(x => x.ToString()); | |
var meth2 = new Func<int, int>(x => x + 1000); | |
var returnnothing = new Action<int>(x => Console.WriteLine("Void call with {0} provided as an argument", x)); | |
var isDiscarded = | |
(bool) | |
binder.GetType().GetProperty("Microsoft.CSharp.RuntimeBinder.ICSharpInvokeOrInvokeMemberBinder.ResultDiscarded", | |
BindingFlags.NonPublic | | |
BindingFlags.Instance | | |
BindingFlags.FlattenHierarchy).GetValue( | |
binder, null); | |
if (isDiscarded) | |
{ | |
returnnothing.DynamicInvoke(args); | |
result = null; | |
} | |
else | |
result = new ServiceAgent {PossibleMethods = new[] {meth1.Method, meth2.Method}, Args = args}; | |
return true; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment