RSCG- part 15 – Expression Generator

 

 

name Property Expression Generator
nuget

https://www.nuget.org/packages/AOPMethodsCommon/
https://www.nuget.org/packages/AOPMethodsGenerator/

link http://msprogrammer.serviciipeweb.ro/category/roslyn/
author Andrei Ignat

This will generate code to add function to be used with Entity Framework to search for any property of a class
 

The code that you start with is


    [AutoMethods(template = TemplateMethod.CustomTemplateFile, CustomTemplateFileName = "CreateMetadata.txt")]

    public partial class Person

    {

        public int ID { get; set; }

        public string FirstName { get; set; }

        public string LastName { get; set; }

        public DateTime? DateOfBirth {get;set;}

    }


The code that you will use is



    var queryCnt = Metadata_Person.expr_FirstName_Contains("9");             

    var pers= await cnt.Person.Where(queryCnt).ToArrayAsync();

    Console.WriteLine(pers.Length);

    

    

    queryCnt = Metadata_Person.expr_LastName_NullOrWhite();

    pers = await cnt.Person.Where(queryCnt).ToArrayAsync();

    Console.WriteLine(pers.Length);

    

    

    var queryID = Metadata_Person.expr_ID_Equal(7);

    var pId = await cnt.Person.FirstOrDefaultAsync(queryID);

    Console.WriteLine(pId.FirstName);

    

    

    queryID = Metadata_Person.expr_ID_Contains(7,9);

    pers = await cnt.Person.Where(queryID).ToArrayAsync();

    Console.WriteLine(pers.Length);

    

    

    var nullBirthDateQuery = Metadata_Person.expr_DateOfBirth_Null();

    var birthNull = await cnt.Person.Where(nullBirthDateQuery).ToArrayAsync();

    Console.WriteLine(birthNull.Length);

    

    var query = Metadata_Person.FindEx("ID", SearchCriteria.Equal, 99);

    pers = await cnt.Person.Where(query).ToArrayAsync();

    Console.WriteLine(pers.Length);

    

    query = Metadata_Person.FindEx("DateOfBirth", SearchCriteria.FindNull);

    pers = await cnt.Person.Where(query).ToArrayAsync();

    Console.WriteLine(pers.Length);

 

The code that is generated is


    [CompilerGenerated]                                                                                                                                                

    public partial class Metadata_Person{

    

        

        

        //public const string prop_ID = "ID";    

        //public static readonly Func<Person,int> func_ID = (it=>it.ID);

        //public static readonly Expression<Func<Person,int>> expr_ID = (it=>it.ID);

        public static Expression<Func<Person,bool>> expr_ID_Equal(int value)=> (it=>it.ID == value);

        public static Expression<Func<Person,bool>> expr_ID_Diff(int value)=> (it=>it.ID != value);

        public static Expression<Func<Person,bool>> expr_ID_Contains(params int[] value)=> (it=> value.Contains(it.ID) );

        

        //int

        

        

        

        

        

            

        public static Expression<Func<Person,bool>> expr_ID_Greater(int value)=> (it=>it.ID > value);

        public static Expression<Func<Person,bool>> expr_ID_GreaterOrEqual(int value)=> (it=>it.ID >= value);

        public static Expression<Func<Person,bool>> expr_ID_Less(int value)=> (it=>it.ID < value);

        public static Expression<Func<Person,bool>> expr_ID_LessOrEqual(int value)=> (it=>it.ID <= value);

        

        

                

        

        //public const string prop_FirstName = "FirstName";    

        //public static readonly Func<Person,string> func_FirstName = (it=>it.FirstName);

        //public static readonly Expression<Func<Person,string>> expr_FirstName = (it=>it.FirstName);

        public static Expression<Func<Person,bool>> expr_FirstName_Equal(string value)=> (it=>it.FirstName == value);

        public static Expression<Func<Person,bool>> expr_FirstName_Diff(string value)=> (it=>it.FirstName != value);

        public static Expression<Func<Person,bool>> expr_FirstName_Contains(params string[] value)=> (it=> value.Contains(it.FirstName) );

        

        //string

        

        

            

        public static Expression<Func<Person,bool>> expr_FirstName_Null()=> (it=>it.FirstName == null);            

        

            

        

    

        public static Expression<Func<Person,bool>> expr_FirstName_NullOrWhite()=> (it=>string.IsNullOrWhiteSpace(it.FirstName));

    

        public static Expression<Func<Person,bool>> expr_FirstName_Ends(string value)=> (it=>it.FirstName.StartsWith (value));

        public static Expression<Func<Person,bool>> expr_FirstName_Starts(string value)=> (it=>it.FirstName.EndsWith(value));

        public static Expression<Func<Person,bool>> expr_FirstName_Contains(string value)=> (it=>it.FirstName.Contains(value));    

        

        

        

        

                

        

        //public const string prop_LastName = "LastName";    

        //public static readonly Func<Person,string> func_LastName = (it=>it.LastName);

        //public static readonly Expression<Func<Person,string>> expr_LastName = (it=>it.LastName);

        public static Expression<Func<Person,bool>> expr_LastName_Equal(string value)=> (it=>it.LastName == value);

        public static Expression<Func<Person,bool>> expr_LastName_Diff(string value)=> (it=>it.LastName != value);

        public static Expression<Func<Person,bool>> expr_LastName_Contains(params string[] value)=> (it=> value.Contains(it.LastName) );

        

        //string

        

        

            

        public static Expression<Func<Person,bool>> expr_LastName_Null()=> (it=>it.LastName == null);            

        

            

        

    

        public static Expression<Func<Person,bool>> expr_LastName_NullOrWhite()=> (it=>string.IsNullOrWhiteSpace(it.LastName));

    

        public static Expression<Func<Person,bool>> expr_LastName_Ends(string value)=> (it=>it.LastName.StartsWith (value));

        public static Expression<Func<Person,bool>> expr_LastName_Starts(string value)=> (it=>it.LastName.EndsWith(value));

        public static Expression<Func<Person,bool>> expr_LastName_Contains(string value)=> (it=>it.LastName.Contains(value));    

        

        

        

        

                

        

        //public const string prop_DateOfBirth = "DateOfBirth";    

        //public static readonly Func<Person,System.DateTime?> func_DateOfBirth = (it=>it.DateOfBirth);

        //public static readonly Expression<Func<Person,System.DateTime?>> expr_DateOfBirth = (it=>it.DateOfBirth);

        public static Expression<Func<Person,bool>> expr_DateOfBirth_Equal(System.DateTime? value)=> (it=>it.DateOfBirth == value);

        public static Expression<Func<Person,bool>> expr_DateOfBirth_Diff(System.DateTime? value)=> (it=>it.DateOfBirth != value);

        public static Expression<Func<Person,bool>> expr_DateOfBirth_Contains(params System.DateTime?[] value)=> (it=> value.Contains(it.DateOfBirth) );

        

        //System.DateTime?

        

        

            

        public static Expression<Func<Person,bool>> expr_DateOfBirth_Null()=> (it=>it.DateOfBirth == null);            

        

        

        

            

        public static Expression<Func<Person,bool>> expr_DateOfBirth_Greater(System.DateTime? value)=> (it=>it.DateOfBirth > value);

        public static Expression<Func<Person,bool>> expr_DateOfBirth_GreaterOrEqual(System.DateTime? value)=> (it=>it.DateOfBirth >= value);

        public static Expression<Func<Person,bool>> expr_DateOfBirth_Less(System.DateTime? value)=> (it=>it.DateOfBirth < value);

        public static Expression<Func<Person,bool>> expr_DateOfBirth_LessOrEqual(System.DateTime? value)=> (it=>it.DateOfBirth <= value);

        

        

        

    

        public static Expression<Func<Person,bool>> FindEx(string nameProp, SearchCriteria search, object value = null)

        {

            

            

            

            if(string.Compare("ID",nameProp,StringComparison.CurrentCultureIgnoreCase) == 0)

            switch(search){

                case SearchCriteria.None:

                    return null;

                

                case SearchCriteria.Equal:

                    var orig= (int) value;

                    return expr_ID_Equal(orig);

                default:

                    throw new ArgumentException("cannot find for ID case  "+search);

            }

            

                        

            

            if(string.Compare("FirstName",nameProp,StringComparison.CurrentCultureIgnoreCase) == 0)

            switch(search){

                case SearchCriteria.None:

                    return null;

                

                case SearchCriteria.FindNull:

                    return expr_FirstName_Null();

                

                case SearchCriteria.Equal:

                    var orig= (string) value;

                    return expr_FirstName_Equal(orig);

                default:

                    throw new ArgumentException("cannot find for FirstName case  "+search);

            }

            

                        

            

            if(string.Compare("LastName",nameProp,StringComparison.CurrentCultureIgnoreCase) == 0)

            switch(search){

                case SearchCriteria.None:

                    return null;

                

                case SearchCriteria.FindNull:

                    return expr_LastName_Null();

                

                case SearchCriteria.Equal:

                    var orig= (string) value;

                    return expr_LastName_Equal(orig);

                default:

                    throw new ArgumentException("cannot find for LastName case  "+search);

            }

            

                        

            

            if(string.Compare("DateOfBirth",nameProp,StringComparison.CurrentCultureIgnoreCase) == 0)

            switch(search){

                case SearchCriteria.None:

                    return null;

                

                case SearchCriteria.FindNull:

                    return expr_DateOfBirth_Null();

                

                case SearchCriteria.Equal:

                    var orig= (System.DateTime?) value;

                    return expr_DateOfBirth_Equal(orig);

                default:

                    throw new ArgumentException("cannot find for DateOfBirth case  "+search);

            }

            

            

            throw new ArgumentException("cannot find property  "+nameProp);

            

        }

    

    }

Example Code: https://github.com/ignatandrei/RSCG_Examples/tree/main/PropertyExpressionGenerator

RSCG- part 14 – DP_Decorator

 

 

name AutoInterface
nuget

https://www.nuget.org/packages/BeaKona.AutoInterfaceGenerator

link https://github.com/beakona/AutoInterface
author beakona

Implement the Design Pattern Decorator. Based on template – you can modify the source code generated
 

The code that you start with is


    public interface ICoffee                                                                                               

    {

        public int Price { get; }

        public string Description { get; }

    }

    

    public class SimpleCoffee : ICoffee

    {

        public SimpleCoffee()

        {

            Price = 3;

            Description = "Simple Coffee";

        }

        public int Price { get; set; }

        public string Description { get; set; }

    

    public partial class MilkDecorator : ICoffee

    {

        [BeaKona.AutoInterface(TemplateLanguage = "scriban", TemplateBody = SimpleCoffee.TemplateCoffeeDecorator)]

        private readonly ICoffee coffee;

    

        public int DecoratorPrice { get; set; } = 1;

        public MilkDecorator(ICoffee coffee)

        {

            this.coffee = coffee;

        }

    

    

    

    }

    

    public partial class ChocoDecorator : ICoffee

    {

        [BeaKona.AutoInterface(TemplateLanguage = "scriban", TemplateBody = SimpleCoffee.TemplateCoffeeDecorator)]

        private readonly ICoffee coffee;

    

        public int DecoratorPrice { get; set; } = 2;

        public ChocoDecorator(ICoffee coffee)

        {

            this.coffee = coffee;

        }

    

    

    }

    


The code that you will use is



    SimpleCoffee s = new SimpleCoffee();

    Console.WriteLine(s.Description +" with Price "+ s.Price);

    ICoffee withMilk = new MilkDecorator(s);

    Console.WriteLine(withMilk.Description} +" with Price "+ withMilk.Price);

    ICoffee withMilkAndChoco = new ChocoDecorator(withMilk);

    Console.WriteLine(withMilkAndChoco.Description +" with Price "+ withMilkAndChoco.Price);

 

The code that is generated is


    partial class MilkDecorator                                                        

    {

        int ICoffee.Price

        {

            get

            {

                    return ((ICoffee)this.coffee).Price + DecoratorPrice;

            }

        }

    

        string ICoffee.Description

        {

            get

            {
                    var name = this.GetType().Name.Replace("Decorator","");

                    return ((ICoffee)this.coffee).Description + " with " + name;

            }

        }

    }

Example Code: https://github.com/ignatandrei/RSCG_Examples/tree/main/DP_Decorator

RSCG- part 13 – IFormattable

 

 

name IFormattable
nuget

https://www.nuget.org/packages/AOPMethodsCommon/
https://www.nuget.org/packages/AOPMethodsGenerator/

link http://msprogrammer.serviciipeweb.ro/category/roslyn/
author Andrei Ignat

This will generate code to add IFormattable to any class, based on the properties of the class
 

The code that you start with is


    [AutoMethods(CustomTemplateFileName = "CreateFormattable.txt", template = TemplateMethod.CustomTemplateFile)]                    

    partial class Department

    {

        public int ID { get; set; }

        public string Name { get; set; }

    

    }

    [AutoMethods(CustomTemplateFileName = "CreateFormattable.txt", template = TemplateMethod.CustomTemplateFile)]

    partial class Employee

    {

        public int ID { get; set; }

        public string Name { get; set; }

    

        public Department dep { get; set; }

        

    }


The code that you will use is



    var e = new Employee();

    e.ID = 1;

    e.Name = "Andrei";

    e.dep = new Department();

    e.dep.Name = "IT";

    

    Console.WriteLine(e.ToString("for employee with id = {id} the name is {name} and department is {dep?.Name}", null)); 

    

    e.dep = null;

    

    Console.WriteLine(e.ToString("for employee with id = {id} the name is {name} and department is {dep?.Name}", null));

    

 

The code that is generated is


    [GeneratedCode("AOPMethods", "2021.2.27.640")]                                             

    [DebuggerDisplay(" ID = {ID} Name = {Name} dep = {dep}")]

    partial class Employee: IFormattable{

        public object ValueProperty(string val){

            val = val.Replace("?","");

                if(string.Compare("ID",val,StringComparison.CurrentCultureIgnoreCase)==0) {

                    return this.ID;

                }

                if(string.Compare("Name",val,StringComparison.CurrentCultureIgnoreCase)==0) {

                    return this.Name;

                }

                if(string.Compare("dep",val,StringComparison.CurrentCultureIgnoreCase)==0) {

                    return this.dep;

                }

            throw new ArgumentException("cannot find "+ val);

        }

        

        //adapted from https://haacked.com/archive/2009/01/14/named-formats-redux.aspx/

        private object Eval(string expression,IFormatProvider formatProvider)

        {

            if (expression.Contains("."))

            {

                var splut = expression.Split(".");

                bool canBeNull=splut[0].Contains("?");

                dynamic d = ValueProperty(splut[0]);

                if(canBeNull && d == null)

                    return null;

                for(var i=1; i<splut.Length;i++){

                    canBeNull=splut[i].Contains("?");

                    d=d.ToString("{"+splut[i]+"}",formatProvider);

                    if(canBeNull && d == null)

                        return null;

                }

                return d;

                

            }

    

            return ValueProperty(expression);

    

        }

    

    

        

        public string ToString(string format, IFormatProvider formatProvider)

        {

            if (format == null)

                throw new ArgumentNullException("format");

    

            List<object> values = new List<object>();

            string rewrittenFormat = Regex.Replace(format,

                delegate (Match m)

                {

                    Group startGroup = m.Groups["start"];

                    Group propertyGroup = m.Groups["property"];

                    Group formatGroup = m.Groups["format"];

                    Group endGroup = m.Groups["end"];

    

                    values.Add((propertyGroup.Value == "0")

            ? this

            : Eval(propertyGroup.Value, formatProvider));

    

                    int openings = startGroup.Captures.Count;

                    int closings = endGroup.Captures.Count;

    

                    return openings > closings || openings % 2 == 0

                ? m.Value

                : new string('{', openings) + (values.Count - 1)

                + formatGroup.Value

                + new string('}', closings);

                },

                RegexOptions.Compiled

                | RegexOptions.CultureInvariant

                | RegexOptions.IgnoreCase);

    

            return string.Format(formatProvider, rewrittenFormat, values.ToArray());

        }

    

    }

Example Code: https://github.com/ignatandrei/RSCG_Examples/tree/main/IFormattable

Doi MVP si doua prezentari despre Xamarin , Machine Learning si Azure

Prezentare 1:

Titlu : Cross-platform mobile application with Xamarin and Integration with Azure DevOps`

Descriere: Just a few clicks and you will have your app up and running inside out favorite DevOps Tool. You can create your dedicated Xamarin pipeline from the portal. Join me to find out more!

Speaker: Codrina Merigo , https://mvp.microsoft.com/en-us/PublicProfile/5003771?fullName=Codrina%20Merigo

 

Prezentare 2:

Titlu:
Deploying a Machine Learning Model with Azure ML Pipelines

Descriere:
Azure Machine Learning pipelines are independently executable workflows of complete machine learning tasks. They are extremely flexible, and can be used for a large variety of scenarios, from simple offline scoring scenarios, to complex deep learning architectures.

During this talk Vlad will discuss the difference between online and offline scoring, the need for applying solid development principles such as SOLID in machine learning, and how pipelines help in that regard.

He will also show how to create a pipeline for deploying and running a simple model, and discuss possibilities for improvement.

Speaker: Vlad Iliescu, https://vladiliescu.net/

 

Va fi miine, 9 martie, ora 19:30: https://www.meetup.com/Bucharest-A-D-C-E-S-Meetup/events/275819326/

 

RSCG – Curry – Partial function – part 12

 

 

name PartiallyApplied
nuget

https://www.nuget.org/packages/PartiallyApplied/

link https://github.com/JasonBock/PartiallyApplied
author Andrei Ignat

This will generate curry for your functions
 

The code that you start with is


    public class Accounting                                            

    {

        public static float Discount( float discount, float price)

        {

            var val= price * (1- discount);

            return val;

        }

    }


The code that you will use is



    var disc10Percent = Partially.Apply(Accounting.Discount, 1/10f);

    Console.WriteLine(disc10Percent(disc10Percent(100)));

 

The code that is generated is


    public static partial class Partially

    {

           public static Func<float, float> Apply(Func<float, float, float> method, float discount) =>

                  new((price) => method(discount, price));

    }

Example Code: https://github.com/ignatandrei/RSCG_Examples/tree/main/PartiallyFunction

RSCG- Method Decorator – part 11

 

 

name Method decorator
nuget

https://www.nuget.org/packages/AOPMethodsCommon/
https://www.nuget.org/packages/AOPMethodsGenerator/

link http://msprogrammer.serviciipeweb.ro/category/roslyn/
author Andrei Ignat

This will generate code to decorate methods with anything you want ( stopwatch, logging , authorization…)
 

The code that you start with is


    [AutoMethods(template =TemplateMethod.CustomTemplateFile,MethodPrefix ="prv" ,CustomTemplateFileName ="MethodDecorator.txt")]

    public partial class Person

    {

         public string FirstName{ get; set; }

         public string LastName { get; set; }

    

         private string prvFullName()

         {

              return FirstName + " " + LastName;

         }

    }


The code that you will use is



    var p = new Person();                 

    p.FirstName = "Andrei";

    p.LastName = "Ignat";

    Console.WriteLine(p.FullName());

 

The code that is generated is


    [GeneratedCode("AOPMethods", "2021.2.22.1125")]                                                                 

    [CompilerGenerated]

    public partial class Person{

              

         public  string FullName (

                   

         [CallerMemberName] string memberName = "",

         [CallerFilePath] string sourceFilePath = "",

         [CallerLineNumber] int sourceLineNumber = 0){

              var sw=Stopwatch.StartNew();

              try{

                   Console.WriteLine("--prvFullName start ");

                   Console.WriteLine("called from class :"+memberName );

                   Console.WriteLine("called from file :"+sourceFilePath );

                   Console.WriteLine("called from line :"+sourceLineNumber );

                        prvFullName();

              }

              catch(Exception ex){

                   Console.WriteLine("error in prvFullName:" + ex.Message);

                   throw;

              }

              finally{

                   Console.WriteLine($"--------prvFullName end in {sw.Elapsed.TotalMilliseconds}");

              }

    

    

         }//end FullName

         

         

    }

Example Code: https://github.com/ignatandrei/RSCG_Examples/tree/main/MethodDecorator

RSGC- Dynamic Mock – part 10

 

 

name MockSourceGenerator
nuget

https://www.nuget.org/packages/MockSourceGenerator/

link https://github.com/hermanussen/MockSourceGenerator/
author Robin Hermanussen

This will generate Mock classes directly for any interface – with your implementation.
 

The code that you start with is


    public interface IMatOps               

    {

        public int Add(int a, int b);

    

        public int Division(int a, int b);

    }


The code that you will use is



    var mock = (IMatOps)new MatOpsMock

    {

        MockAdd = (a, b) => a+b,

        MockDivision = (a,b)=> a/b

    };

 

The code that is generated is


    public partial class MatOpsMock : global::MatOps.IMatOps                                                                                                           

    {

        /// <summary>

        /// Set this to true, if you want members that don't have a mock implementation

        /// to return a default value instead of throwing an exception.

        /// </summary>

        public bool ReturnDefaultIfNotMocked { get; set; }

    

        private System.Collections.Generic.List<HistoryEntry> historyEntries = new System.Collections.Generic.List<HistoryEntry>();

        public System.Collections.ObjectModel.ReadOnlyCollection<HistoryEntry> HistoryEntries

        {

            get

            {

                return historyEntries.AsReadOnly();

            }

        }

    

    

        /// <summary>

        /// Implemented for type global::MatOps.IMatOps (Public, same assembly: False)

        /// </summary>

        public Func<int,int,int>? MockAdd { get; set; }

        public int Add(int a, int b)

        {

            historyEntries.Add(new HistoryEntry("Add", new [] { $"{a}", $"{b}" }));

    

            if (MockAdd == null)

            {

                if (ReturnDefaultIfNotMocked)

                {

                    return default(int);

                }

                else

                {

                    throw new NotImplementedException("Method 'MockAdd' was called, but no mock implementation was provided");

                }

            }

    

            return MockAdd(a, b);

        }

    

        /// <summary>

        /// Implemented for type global::MatOps.IMatOps (Public, same assembly: False)

        /// </summary>

        public Func<int,int,int>? MockDivision { get; set; }

        public int Division(int a, int b)

        {

            historyEntries.Add(new HistoryEntry("Division", new [] { $"{a}", $"{b}" }));

    

            if (MockDivision == null)

            {

                if (ReturnDefaultIfNotMocked)

                {

                    return default(int);

                }

                else

                {

                    throw new NotImplementedException("Method 'MockDivision' was called, but no mock implementation was provided");

                }

            }

    

            return MockDivision(a, b);

        }

    }

Example Code: https://github.com/ignatandrei/RSCG_Examples/tree/main/DynamicMocking

Andrei Ignat weekly software news(mostly .NET)

* indicates required

Please select all the ways you would like to hear from me:

You can unsubscribe at any time by clicking the link in the footer of our emails. For information about our privacy practices, please visit our website.

We use Mailchimp as our marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp's privacy practices here.