GithubHelp home page GithubHelp logo

geranium.reflection's Introduction

Geranium.Reflection

NuGet version

.NET reflection provided by ExpressionTrees. An alternative for reflection by extensions methods based on Expressions. This extensions allow create new instances without activator, set or get property values of unknown types and unknown properties, check equality with unknown type default value, call object methods and extension methods avoiding Invoke, and couple of non-expression extensions for as/is.

Benchmarks

Full table available here: Benchmark resuts

New

New() average faster then Activator in 10 times, short info:

Method Mean Allocated
New 30.655 ns 72 B
New (params) 72.224 ns 144 B
Activator 558.993 ns 568 B

Get

GetPropValue() average faster then PropertyInfo in 2-5 times

Method Mean Allocated
Reflection 103.186 ns 24 B
GetPropValue 17.372 ns 24 B

Set

SetPropValue() average faster then PropertyInfo in 2-5 times

Method Mean Allocated
Reflection 118.99 ns 24 B
SetPropValue 32.04 ns 128 B

Short list of features:

  • New
  • get/set
  • default
  • is
  • as
  • call

Supported targets:

  • net6.0+
  • netcoreapp3.1+
  • netstandard2.1+
  • net46+

New

Alternative for Activator.CreateInstance provided by Expression.New lambda cached by System.Type into Delegate.

Available methods

  • object New(this object obj)
  • object New<T1, T2, ..., T16>(this object obj, T1 arg1,T2 arg2,..., T16 arg16)
  • object New(this object obj, params object[] args)

Examples

Getting List<T> as IList of Type in runtime:

public static IList IList(this Type type)
{
    return typeof(List<>).MakeGenericType(type)
        .New()
        .As<IList>();
}

Create and apply migration from migration type:

void RunMigration(Type migrationType)
{
    var migration = migrationType.New().As<CodegenMigration>();
    ...
    migration.Apply();
    ...
}

Get property / Set property

Get property values:

There is three methods for getting value from property based on Expression.PropertyOrField:

  • object GetPropValue(this object obj, string propName)
  • TValue GetPropValue<TValue>(this object obj, string propName)
  • TValue GetPropValue<THost, TValue>(this THost obj, string propName)

Example of getting 'Id' value of uknown type:

var rowAccess = new RowAccess
{
    Type = typeof(T),
    IdValue = entity.GetPropValue("Id") // value can be long/string/Guid or something
};

Set property values:

There is only one method for setting value:

  • void SetPropValue(this object obj, string propName, object propValue)

But it can works different based on passed value:

  • Usually (for nullable too) its just set value by lambda
  • For enum values it wraps action with Enum.Parse(value.ToString())
  • If you pass wrong type for value, it will try convert by Convert.ChangeType

Example method of setting 'Id' value when you don't know type:

public static void SetId<TId>(this object obj, TId value) 
=> obj.SetPropValue("Id", value);

public static void SetId(this object obj, object value) 
=> obj.SetPropValue("Id", value);

Example of create IList and bind to object:

var type = obj.GetType();
var prop = type.GetProperty('Users');
var list = prop.IList();
obj.SetPropValue(prop.Name, list);

Default

Alternative of default for System.Type in runtime based on Expression.Default() with cache available by DefaultExtensions.Default(this Type type):

var type = obj.GetType();
var prop = type.GetProperty('Id');
var value = prop.GetValue(obj);
if(value.Equals(type.Default())
    Console.WriteLine("Property is not initialized!");

Extensions provided not by ExpressionTree

Equivalent of C# 'as'

  • As<T>(this object)
  • As<T>(this object, bool throw)
  • As<T>(this object, T default)

Equivalent of C# 'is/not' check

  • Is<T>(this object)
  • Is<T>(this object, out T match)
  • IsNot<T>(this object)
  • IsNot<T>(this object, out T match)
  • Is<T>(this Type)
  • Is<T>(this Type, out T match)
  • IsNot<T>(this Type)
  • IsNot<T>(this Type, out T match)

Additional methods for 'is something'

  • IsSimple
  • IsPrimitive
  • IsNumericType
  • IsDateType
  • IsNullable
  • IsNullablePrimitive
  • IsAnonymousType
  • IsICollection
  • IsDbCollection

Additional methods for IEnumerable

'String' checks differenlty

  • IsEmpty
  • IsNotEmpty

Call

Extensions for call methods by ExpressionTrees Available methods for 'call':

  • obj.Call("Equalls",null);
  • dbCtx.CallGeneric("Set",new Type[]{ typeof(User) });
  • typeof(Console).CallStatic("WriteLine", "log");
  • list.CallExtension("ToList",typeof("EnumerableExtensions");

Overloads for call static generic, call generic extension, Call with T result etc included.

Example of using Call chain with LiteDatabase: gettin anonymous class from store in runtime:

var liteDbCollectionQueryable = LiteDb
    .CallGeneric("GetCollection", new Type[] { type })
    .Call("FindAll")
    .CallGenericExtension("ToList", typeof(Enumerable), new[] { type })
    .CallGenericExtension("AsQueryable", typeof(Queryable), new[] { type });
    
var filtered = SelectionModelConverter
    .CallGeneric("Convert", new Type[] { type }, selection, liteDbCollectionQueryable)
    .GetPropertyExprRaw("Result");
    
var (filteredPropertyConverted, anonymousType) = SelectionModelConverter
    .CallGeneric<(IQueryable, Type)>("ConvertProperties", new Type[] { type }, selection.Properties, filtered); // returns IQueryable and anonymousType
    
var materialize = filteredPropertyConverted.CallGenericExtension("ToList", typeof(Enumerable), new[] { anonymousType });

TypeFromAssemblyExtensions

Extensions for getting Types and instances of Type from Assembly and assembly names loaded from AppDomain.Current.BasePath.

Note about performance (package version 1.0.0)

That's not speed-up alternative. You can check it by run some benchmarks. That's alternative of System.Reflection. With .NET6 all techniques of 'speed-up' by ExpressionTrees and even source generators is pointless because of reflection improvements described here: https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-6/#reflection But still it can be useful alternative for full .NET Framework with 'old' runtime.

geranium.reflection's People

Contributors

aneteanetes avatar shockthunder avatar kant2002 avatar halloneo avatar

Stargazers

 avatar  avatar Alexander avatar pedoc avatar Daniel Horn avatar Arash Shabbeh avatar Aristarkh Zagorodnikov avatar  avatar  avatar Ulysses avatar Moaid Hathot avatar Helmoz avatar Sai Marpaka avatar Coen van den Munckhof avatar Andrejs Agejevs avatar Soar avatar Matt Sanders avatar Kirill Osenkov avatar Ivan Josipovic avatar  avatar Kostiantyn Nesterenko avatar  avatar Friedrich von Never avatar  avatar Bookuha avatar

Watchers

 avatar

geranium.reflection's Issues

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.