Coder Social home page Coder Social logo

ekonbenefits / dynamitey Goto Github PK

View Code? Open in Web Editor NEW
355.0 21.0 44.0 671 KB

(pronounced dyna-mighty) flexes DLR muscle to do meta-mazing things in .net

License: Apache License 2.0

Shell 1.02% C# 98.98%
dynamic metaprogramming dotnet reflection

dynamitey's Introduction

Dynamitey

(pronounced dyna-mighty) flexes DLR muscle to do meta-mazing things in .net

Dynamitey is available Nuget NuGet

You can find the latest bleed edge on MyGet MyGet Pre Release

Framework Platform Status
All Windows Build status
.NET Core Linux/Mac/Windows Actions Status
Compiled For
.Net Std 2.0
.Net Std 1.5
.Net 4.0
Portable .NET 4.5, Silverlight 4 & 5, WinRT, Win Phone 8

Change Log

Install with Nuget:

PM> Install-Package Dynamitey

Meta-mazing Features

  • Easy Fast DLR based Reflection -- oooo
  • Clean syntax for using types from late bound libraries -- ahhh
  • Dynamic Currying -- whaaa?
  • Manipulation of Tuples -- wowzers
  • Inline Object Graph Intialization Syntax whoa
  • DynamicObject base types for many things -- jenkies
  • Extension to instance method conversion -- o_O

dynamitey's People

Contributors

dotnetchris avatar eltjo-k avatar jbtule avatar jeffska avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dynamitey's Issues

Generic method call fails

I tried running the invocation of a generic typed method of a class and got an exception. Switching to use raw .NET reflection with MakeGenericMethod I was able to make the call.

I didn't see a test for this, so I may make a fork and submit a pr with a failing test.

Dynamic.InvokeMember throws RuntimeBinderException on async method

Hi,

I'm working with Azure.Data.Tables nuget package and while i'm trying to call an async method on an internal class a RuntimeBinderException is thrown.
Here is a test that highlights this error.

using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Azure.Data.Tables.Models;
using Dynamitey;
using NUnit.Framework;

namespace Azure.Data.Tables.WithDynamitey.Tests
{
    public class WhereAsyncShould
    {
[Test]
        public async Task Failing()
        {
            string tableName = "WhereAsyncShould";
            var serviceClient = new TableServiceClient("UseDevelopmentStorage=true");
            var client = serviceClient.GetTableClient(tableName);
            var restClient = Dynamic.InvokeGet(client, "_tableOperations");


            var response = await Dynamic.InvokeMember(restClient, new InvokeMemberName("QueryEntitiesAsync", false), new object[]
            {
                new InvokeArg("table", tableName),
                new InvokeArg("timeout", (int?)10),
                new InvokeArg("queryOptions", BuildQueryOptions(client)),
                new InvokeArg("cancellationToken", CancellationToken.None)
            });

            Assert.That(response, Is.Not.Null);
        }

        private static dynamic BuildQueryOptions(TableClient tableClient)
        {
            var t = typeof(TableItem).Assembly.GetType("Azure.Data.Tables.Models.QueryOptions");
            var opts = Dynamic.InvokeConstructor(t);
            Dynamic.InvokeSet(opts, "Format", Dynamic.InvokeGetChain(tableClient, "_defaultQueryOptions.Format"));
            return opts;
        }
}

Any help would be appreciated.

Static property set followed by get fails with RuntimeBinderException

After experimenting with impromptu-interface, and then dynamitey, I've found them interesting, powerful, and enjoyable to use. Thank-You for making such excellent code available.

Note: I used v1.0.2.0 as released via NuGet (the latest release at the time of this writing) to reproduce this reported issue.

I did find that in dynamitey, individual calls to get or set a value to a static property work fine. However, a RuntimeBinderException is thrown when two operations (such as a set followed by a get) are performed on a static property.

The exception thrown is:

...DynamiteyTest.DynamiteyStaticPropertySetFollowedByGetTest threw exception: 
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: '..DynamiteyTest.TestClass.StaticProperty.get': cannot explicitly call operator or accessor

This test class running under Dot Net v4.5 demonstrates the issue:

    [TestClass]
    public class DynamiteyTest
    {
        private class TestClass
        {
            public static int StaticProperty { get; set; }
        }

        [TestMethod]
        public void DynamiteyStaticPropertySetFollowedByGetTest()
        {
            var staticContext = InvokeContext.CreateStatic;
            Dynamic.InvokeSet(staticContext(typeof(TestClass)), "StaticProperty", 42);
            var tOut = Dynamic.InvokeGet(staticContext(typeof(TestClass)), "StaticProperty");
            Assert.AreEqual(42, tOut);
        }
    }

My expertise with the DLR begins and ends with the usage of the c# keyword "dynamic" and some limited usage of impromptu-interface and dynamitey. I looked for references that this may be a known issue, but didn't find any. So I decided to report it.

Again, thanks for your efforts...

Async

@jbtule I'm trying to use Impromptu Interface to assign an asynchronous function to an interface method:
expando.Add("Method Name", Return<Customer>.Arguments<Customer>(async (it) => await MyAsyncMethod(prop.Name, it)));

Unfortunately, Dynamitey does not support asynchronous assignments. Is this something that would be fairly easy to add?

Thanks in advance.

InvokeGet on an instance field works, while it fails on static field.

As a first note, I work on mono, not the very newest version from git, but quite new. I may test it on other versions as well, but I will have problems testing it on .NET.

Wiki tells us, that InvokeGet is for properties, yet I see it works with instance fields as well.

So this works:

var value = Dynamic.InvokeGet(target, "myField");

but this does not:

var context = InvokeContext.CreateStatic(target.GetType());
var value = Dynamic.InvokeGet(context, "myStaticField");

It fails with:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:
`TargetType` does not contain a definition for `get_myStaticField`.

Am I doing something wrong or is it a bug?

InvokeGet with static context fails

I'm migrating an older projects to .NET Standard. Previously I used ImpromputInterface:

Impromptu.InvokeGet(type.WithStaticContext(), "Context");

Where the type is for example a nested private class within a test fixture:

public class ContextResolverTests
{
    private class GenericType
    {
        private static string Context => "Text";
    }
}

Now I want to target netstandard1.5 so I replaced the original implementation with Dynamitey

var staticContext = InvokeContext.CreateStatic;
return Dynamic.InvokeGet(staticContext(type), "Context");

And it stopped working!

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException : 
   'JsonLD.Entities.Tests.ContextResolverTests.GenericType' does not contain a definition for 'Context'

Apparently the class has to be public and cannot be nested. Here's my repository stripped down. I removed everything, all unnecessary code and replaced paket with plain nuget references, to no avail.

does-not-work.zip

But the real kicker is that I tried to reproduce this from scratch and was completely unable to get the same effect. What is going on?

works.zip

Add support for creating dynamic static objects

After looking at the following unit test:

        [Test]
        public void TestStaticDateTimeMethod()
        {
            var @static = InvokeContext.CreateStatic;
            object tDateDyn = "01/20/2009";
            var tDate = Dynamic.InvokeMember(@static(typeof(DateTime)), "Parse", tDateDyn);
            Assert.AreEqual(new DateTime(2009, 1, 20), tDate);
        }

I was hoping something like this might be possible:

            var @static = InvokeContext.CreateStatic;
            object tDateDyn = "01/20/2009";

            dynamic staticObject = @static(typeof(DateTime));
            var tDate = staticObject.Parse("Parse", tDateDyn);

            Assert.AreEqual(new DateTime(2009, 1, 20), tDate);

Is there some technical reason why this would be impossible?

Thanks!

Get.TryInvokeMember() throws RuntimeBinderException

Hey,

Not sure whether this is an error, but I would expect this to return false if I asked it to call a method which didn't exist.

var anon = new { a = 0 };
var get = new Get(anon);
Assert.False(() => get.TryInvokeMember(binder, args, out result));

Where binder.Name == "NoMethodHere".

I had thought it was the job of the specific language runtime to take an appropriate action (like throw an exception) if asking a DynamicObject to do something it doesn't support. Is that not the case?

Cheers,
Frank.

Question on Dynamic class design

I am trying to define a dynamic object class which I will use for producing a set of exportable records.This object will have its list of properties read from a file and the definition will be added at runtime.

Since I'll be creating a bunch of these classes which have the same definition, how can I efficiently reuse the definition so that I can create the object over and over using the facilities Dynamitey provides?

Part of me feels like this would be easier if the SetProperty method on BaseDictionary was virtual so that I could override this to store additional metadata. But I also wonder if Builder or Factory can help me here.

Any help/guidance is appreciated.

// Possibly could derive from DynamicObjects.Dictionary
public class ExportableObject : BaseObject {
    //More code
}

public class ExportableType {
    public ExportablePropertyDefinition this[string name] {
        get { 
            //getter code
        }
        set {
           // setter code
        }
    }
}

/// This class will be populated from a file or database
public class ExportablePropertyDefinition {
    public string Name {get;set;}
    public Type Type {get;set;}
    public int Index {get;set;}
    public bool IsExportable {get;set;}    
    public object DefaultValue {get;set;}
}

public class Exporter {
   public string Export(IEnumerable<ExportableObject> records, string format) {
       // more code
   }
}

Shorthand for dynamic objects

So today we have

Build<ExpandoObject>.NewObject(RatingName: name, Comment: comment)

For basically approximating

new { RatingName = name, Comment = comment }

That's still pretty verbose. Can we get something like:

Expando.New(RatingName: name, Comment: comment)

Much less goo-ey.

Could not load file or assembly 'ImpromptuInterface, PublicKeyToken=0b1781c923b2975b'

Hi,

I am working on a plugin assembly for a piece of third party software. My plugin references another assembly of mine which eventually references Dynamitey. Now, the other assembly works fine under other circumstances, but when used with the plugin it fails. The error is this:

14:58:57.545: AssemblyResolve looking for ImpromptuInterface, PublicKeyToken=0b1781c923b2975b, requesting assembly N/A
14:58:57.547: Could not resolve assembly ImpromptuInterface, PublicKeyToken=0b1781c923b2975b, trying redirect to self.
TargetInvocation exception: System.TypeInitializationException: The type initializer for 'Dynamitey.Dynamic' threw an exception. ---> System.IO.FileLoadException: Could not load file or assembly 'ImpromptuInterface, PublicKeyToken=0b1781c923b2975b' or one of its dependencies. A strongly-named assembly is required. (Exception from HRESULT: 0x80131044) ---> System.IO.FileLoadException: A strongly-named assembly is required. (Exception from HRESULT: 0x80131044)
   --- End of inner exception stack trace ---
   at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMarkHandle stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName, ObjectHandleOnStack type)
   at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName)
   at System.RuntimeType.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark)
   at System.Type.GetType(String typeName, Boolean throwOnError)
   at Dynamitey.DynamicObjects.LateType..ctor(String typeName)
   at Dynamitey.Dynamic..cctor()
   --- End of inner exception stack trace ---
   at Dynamitey.Dynamic.InvokeGet(Object target, String name)

So when Dynamic.InvokeGet is called, it eventually tries to load (from file?) the assembly named ImpromptuInterface, which is some sort of dynamic assembly created inside Dynamic.cs, i.e. not something that can be loaded from file. Looking at the debug output, I suspect the problem is triggered by the way the 3rd party software resolves plugin assemblies.

If I create a test project and 'statically' reference the plugin assembly, the problem does not occur.

Now, I am not claiming that this is a bug as such in Dynamitey, but maybe it could be made immune to such a problem?

Dynamic.InvokeMember on a Async method which returns a generic ValueTask throws Exception

This original code:

public async ValueTask<VideoWatchPageExtractor> GetVideoWatchPageAsync(
            VideoId videoId,
            CancellationToken cancellationToken = default)
{
 // ....
}

Is called via:

var result = await Dynamic.InvokeMember(_controller, "GetVideoWatchPageAsync", videoId, CancellationToken.None);

And this throws Exception like:

''System.ValueType' does not contain a definition for 'GetAwaiter''

InvalidCastException thrown from InvokeConstructor if passing more than 14 params arguments

from ekonbenefits/impromptu-interface#9: by @jdh28

I have a class that I'm creating dynamically via Dynamic.InvokeConstructor that has params arguments. If I pass in 14 arguments it works, but 15 causes an InvalidCastException:

System.InvalidCastException: The result type 'MyClass' of the dynamic binding produced by binder 'Microsoft.CSharp.RuntimeBinder.CSharpInvokeConstructorBinder' is not compatible with the result type 'System.Type' expected by the call site.

Here is some example code:

    class Program
    {
        static void Main(string[] args)
        {
            var parameters = Enumerable.Range(0, 15).Select(i => i.ToString() as object).ToArray();
            var instance = Dynamic.InvokeConstructor(typeof(MyClass), parameters);
            Console.Out.WriteLine(instance.Args);
        }
    }


    public class MyClass
    {
        public readonly string Args;

        public MyClass(params string[] args)
        {
            Args = String.Join(",", args);
        }
    }

InvokeGet/InvokeSet fails on private properties on Mono

namespace Test1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Dynamic.InvokeSet(new ToTest(), "field", 5));
        }       
    }

    class ToTest
    {
        private int field { get; set; }
    }
}

Fails with Microsoft.Csharp.RuntimeBinder.RuntimeBinderException: Test1.ToTest does not contain a definition for 'field'.

Works on .NET.

Do you think it's a Mono bug or a Dynamitey issue? If it's on Mono side I'll try to extract some code and make a ticket on their bugzilla.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.