Skip to content

Instantly share code, notes, and snippets.

@statianzo
Created April 26, 2010 15:15
Show Gist options
  • Save statianzo/379452 to your computer and use it in GitHub Desktop.
Save statianzo/379452 to your computer and use it in GitHub Desktop.
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