public void CanCreateADynamicAdder() { Func <object[], object> addBody = delegate(object[] args) { var a = (int)args[0]; var b = (int)args[1]; return(a + b); }; // Map LinFu's DynamicObject to an ICanAdd interface var linfuDynamicObject = new DynamicObject(new object()); var returnType = typeof(int); var parameterTypes = new[] { typeof(int), typeof(int) }; linfuDynamicObject.AddMethod("Add", addBody, returnType, parameterTypes); // If it looks like a duck... Assert.IsTrue(linfuDynamicObject.LooksLike <ICanAdd>()); // ...then it must be a duck, right? var somethingThatCanAdd = new SomethingThatAdds(linfuDynamicObject.CreateDuck <ICanAdd>()); somethingThatCanAdd.FirstNumber = 10; somethingThatCanAdd.SecondNumber = 20; Assert.AreEqual(somethingThatCanAdd.AddNumbers(), 30); }
public static object CreateDuck(this TypeSpec spec, Type targetType) { var type = new DynamicType(spec); var dynamic = new DynamicObject(); dynamic += type; return(dynamic.CreateDuck(targetType)); }
public static T CreateDuck <T>(this TypeSpec spec) where T : class { var type = new DynamicType(spec); var dynamic = new DynamicObject(); dynamic += type; return(dynamic.CreateDuck <T>()); }
public static Object Extend(object toExtend) { var dyn = new DynamicObject(toExtend); dyn.MixWith(new WithId { Id = Guid.New() }); var extended = dyn.CreateDuck <IWithId>(returnValue.GetType().GetInterfaces()); return(extended); }
public static Object Extend(object toExtend) { var dyn = new DynamicObject(toExtend); dyn.MixWith(new WithId { Id = Guid.New() }); var extended = dyn.CreateDuck <IWithId>(); return(extended); }
/// <summary> /// Creates the module from specified data in specified <see cref="AppDomain"/>. /// </summary> /// <param name="moduleInfo">The module info.</param> /// <param name="domain">The module domain.</param> /// <returns>Created module.</returns> public static IModule CreateModule(ModuleInfo moduleInfo, AppDomain domain) { object moduleInstance = domain.CreateInstanceAndUnwrap(moduleInfo.AssemblyName, moduleInfo.TypeName); DynamicObject dynModule = new DynamicObject(moduleInstance); if (dynModule.LooksLike <IModule>() == false) { throw new MissingMethodException("Required methods not found."); } IModule moduleDuck = dynModule.CreateDuck <IModule>(); return(moduleDuck); }
public void ShouldBeAbleToShareTheSameDynamicType() { var typeSpec = new TypeSpec { Name = "Person" }; // Add an age property typeSpec.AddProperty("Age", typeof(int)); // Attach the DynamicType named 'Person' to a bunch of dynamic objects var personType = new DynamicType(typeSpec); var first = new DynamicObject(); var second = new DynamicObject(); first += personType; second += personType; // Use both objects as persons var firstPerson = first.CreateDuck <IPerson>(); var secondPerson = second.CreateDuck <IPerson>(); firstPerson.Age = 18; secondPerson.Age = 21; Assert.AreEqual(18, firstPerson.Age); Assert.AreEqual(21, secondPerson.Age); // Change the type so that it supports the INameable interface typeSpec.AddProperty("Name", typeof(string)); var firstNameable = first.CreateDuck <INameable>(); var secondNameable = second.CreateDuck <INameable>(); firstNameable.Name = "Foo"; secondNameable.Name = "Bar"; Assert.AreEqual("Foo", firstNameable.Name); Assert.AreEqual("Bar", secondNameable.Name); }
/// <summary> /// Creates the module specific domain. /// </summary> /// <param name="module">The module.</param> /// <returns>Created application domain.</returns> private static AppDomain CreateModuleSpecificDomain(ModuleInfo module) { object moduleInstance = Activator.CreateInstance(module.AssemblyName, module.TypeName).Unwrap(); DynamicObject dynModule = new DynamicObject(moduleInstance); if (dynModule.LooksLike <IDomainCreator>()) { return(dynModule.CreateDuck <IDomainCreator>().CreateDomain()); } else { return(null); } }
public void ShouldAllowDuckTyping() { var test = new MockClass(); var dynamic = new DynamicObject(new object()); var duck = dynamic.CreateDuck <ITest>(); // Combine the MockClass implementation with the current // object instance dynamic.MixWith(test); duck.TargetMethod(); duck.TargetMethod <int>(); Assert.AreEqual(2, test.CallCount); }
public void ShouldBeAbleToShareTheSameDynamicType() { var typeSpec = new TypeSpec { Name = "Person" }; // Add an age property typeSpec.AddProperty("Age", typeof(int)); // Attach the DynamicType named 'Person' to a bunch of dynamic objects var personType = new DynamicType(typeSpec); var first = new DynamicObject(); var second = new DynamicObject(); first += personType; second += personType; // Use both objects as persons var firstPerson = first.CreateDuck<IPerson>(); var secondPerson = second.CreateDuck<IPerson>(); firstPerson.Age = 18; secondPerson.Age = 21; Assert.AreEqual(18, firstPerson.Age); Assert.AreEqual(21, secondPerson.Age); // Change the type so that it supports the INameable interface typeSpec.AddProperty("Name", typeof(string)); var firstNameable = first.CreateDuck<INameable>(); var secondNameable = second.CreateDuck<INameable>(); firstNameable.Name = "Foo"; secondNameable.Name = "Bar"; Assert.AreEqual("Foo", firstNameable.Name); Assert.AreEqual("Bar", secondNameable.Name); }
public void ShouldAllowDuckTyping() { MockClass test = new MockClass(); DynamicObject dynamic = new DynamicObject(new object()); ITest duck = dynamic.CreateDuck<ITest>(); // Combine the MockClass implementation with the current // object instance dynamic.MixWith(test); duck.TargetMethod(); duck.TargetMethod<int>(); Assert.AreEqual(2, test.CallCount); }