Year: 2018

Interpreter–part 2 of n – Coding

Series:

  1. http://msprogrammer.serviciipeweb.ro/2018/07/16/interpreterpart-1-of-n/ – Idea
  2. http://msprogrammer.serviciipeweb.ro/2018/07/23/interpreterpart-2-of-n/ – Coding
  3. http://msprogrammer.serviciipeweb.ro/2018/07/30/interpreterpart-3-of-n/ – Testing
  4. http://msprogrammer.serviciipeweb.ro/2018/08/06/interpreterpart-4-of-n/  – Deploy
  5. http://msprogrammer.serviciipeweb.ro/2018/08/13/interpreterpart-5-of-n/ – Documentation
  6. http://msprogrammer.serviciipeweb.ro/2018/08/20/interpreterpart-6-of-n/ – Ecosystem / usage

 

 

Now that we have the idea from interpreter part 1 of what we want to do, start coding thinking about what the code will look like.

We want simple use, like

string textToInterpret = "Export#now:yyyyMMddHHmmss#.csv";
var i = new Interpret();
var nameFile = i.InterpretText(textToInterpret);

So we will have just a function, InterpretText , that will have as a parameter a string and returns the interpreted string.

Now we can start the coding part   .This  is somewhat harder – we make separate functions to interpret environment variables, interpret datetime, guid, interpret file json, and interpret with static functions

For this we will create separate functions , that know how to deal with those cases ( The edge case is loading assemblies – you do not want this time consuming to be done every time you interpret – or to load if it is not necessary)

After this  , in order to have a source control, you upload the code on GitHub : https://github.com/ignatandrei/Interpreter

 

Friday links 276

  1. Ending the Nested Tree of Doom with Chained Promises
  2. Multithreading in C# .NET 4.5 (Part 2) – CodeProject
  3. Useful Reference Books – CodeProject
  4. 16 Useful Mental Life Hacks | Idealist Revolution
  5. Edmond Lau’s answer to What are the questions that can be asked when the interviewer asks ‘Any questions?’ – Quora
  6. Gayle Laakmann McDowell’s answer to What are some interesting coding projects that I can complete in 7-14 days to build my resume for a summer internship? – Quora
  7. McCann Created an Escort Service That Had a Macabre Surprise for Anyone Who Tried It | Adweek
  8. Building and deploying an Outlook 2010 Add-in (part 2 of 2) – MCS UK Solution Development Team
  9. Outlook: Deploying an Outlook 2013 add-in (using InstallShield LE) – EMEA Developer Messaging Team Blog
  10. Humanizr/Humanizer: Humanizer meets all your .NET needs for manipulating and displaying strings, enums, dates, times, timespans, numbers and quantities
  11. rudyhuyn/PluralNet: Improve the localization of your application with support of plural forms. Support all existing languages and decimal numbers. Available for UWP, WinRT, Windows Phone, Xamarin Android and iOS, ASP.Net, .Net apps
  12. Outlook: Deploying an Outlook 2013 add-in (using InstallShield LE) – EMEA Developer Messaging Team Blog
  13. Create your first QnA bot using botframework’s QnA Maker | Robin Osborne
  14. Becoming a better JavaScript developer
  15. 8 Browser Extensions You’ll Love If You Use Trello

Interpreter–part 1 of n – Idea

Series:

  1. http://msprogrammer.serviciipeweb.ro/2018/07/16/interpreterpart-1-of-n/ – Idea
  2. http://msprogrammer.serviciipeweb.ro/2018/07/23/interpreterpart-2-of-n/ – Coding
  3. http://msprogrammer.serviciipeweb.ro/2018/07/30/interpreterpart-3-of-n/ – Testing
  4. http://msprogrammer.serviciipeweb.ro/2018/08/06/interpreterpart-4-of-n/  – Deploy
  5. http://msprogrammer.serviciipeweb.ro/2018/08/13/interpreterpart-5-of-n/ – Documentation
  6. http://msprogrammer.serviciipeweb.ro/2018/08/20/interpreterpart-6-of-n/ – Ecosystem / usage

 

 

For Stankins I need a custom interpreter of serialized data. What this means, exactly ?

Let’ suppose I have an appsetting file with a connection string

{
“SqlServerConnectionString”: “Server=(local)\\SQL2016;Database=tempdb;Trusted_Connection=True;”
}

If I use directly this connection from code, fine( Please be sure that you read carefully https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-2.1&tabs=basicconfiguration ).

The idea is to have some settings that is generating all time from data. Let’s suppose you have to write a .csv file with some data.You want to be unique every time . The common idea is to hardcode the file with the date time :

string file = “SendTo”+ DateTime.Now.ToString(“yyyyMMdd”) + “.csv”

What if the the name of the file should be serialized  ?  You retrieve from config the first part ( “SendTo”) , append the datetime format and the .csv. Later, you figure a better idea – to have a GUID. You will modify the code again and wrote

string file = “SendTo”+ Guid.NewGuid().ToString(“N”) + “.csv”

What if you will have something like storing the fle name in a appSettings.json like

{

“fileName”:”file:SendTo#now:yyyyMMdd#.csv”

}

retrieve with configuration

var builder = new ConfigurationBuilder()
.AddJsonFile(filePath);
var config = builder.Build();

var fileName = config[“fileName”]

and then interpret:

var i = new Interpret();
var str = i.InterpretText(fileName );

 

This will give you in the str the string SendTo20180710.csv.

Next time, when you want Guid, you just modify the appSettings.json

{

“fileName”:”SendTo#guid:N#”.csv”

}

The code remains the same for interpret:

var i = new Interpret();
var str = i.InterpretText(fileName );

 

but the result will be different ,with the guid into the filename

What I intend to support:

-file: appSettings.json

-env: environment

-static: static functions with one variable

-guid: Guid.NewGuid

-now : datetime

But the idea is that I have a class that serializes itself as follow:

{

“ConnectionString”:”#file:SqlServerConnectionString#”,

“FileName”: “SendTo#now:yyyyMMdd#.csv”,

“DriveRoot”:”@static:Path.GetPathRoot(#static:Directory.GetCurrentDirectory()#)@”

“NameSln”:”@static:System.IO.Path.GetFileNameWithoutExtension(#env:solutionPath#)@”,

“newFileName”:”#guid:N#.csv”

}

The first item will be interpreted as ConnectionString : “Server=(local)\\SQL2016;Database=tempdb;Trusted_Connection=True;”

The second item will be interpreted as FileName: “SendTo20180710.csv”

The third item will call the static functions( Directory.GetCurrentDirectory() , Path.GetPathRoot)   from C# and return the result

The fourth item will call Environment variable solutionPath  and give back as an argument to the static function System.IO.Path.GetFileNameWithoutExtension

The fifth will call Guid.NewGuid().ToString(“N”)

All in all, it is another redirection and interpreting of data.

 

Angular , CORS and .NET Core SignalR

I have written a .NET Core  SignalR + Agular Observable of continously delivering the data. (http://msprogrammer.serviciipeweb.ro/2018/06/25/net-core-signalr-hub-angular-observable/ )

The setup is that .NET WebAPI resides in Visual Studio Project ( .sln. .csproj) and Angular Project is separate in another folder.

There are some settings in the development to be done in order to work

  1. Setting CORS in .NET Core  ( not really necessary- see below)
  2. Usually you will not need to set CORS in .NET Core if you plan to deliver Angular and .NET Core in the same site.

    But anyway, to allow anyoneto call you API , you will do something like this :

    services.AddCors();
    services.AddMvc();
    //...
     app.UseCors(it =>it.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
    //if (env.IsDevelopment())
    //{
    //    app.UseDeveloperExceptionPage();
    //}
    
    

    Of course, you can set for a domain, a header , and so on

    Also , do not forget to handle CORS errors – either by commenting the developer exception page, either by using a custom middleware, like https://blog.jonathaneckman.io/handling-net-core-web-api-exceptions-with-an-aurelia-fetch-interceptor/

  3. Setting  CORS like it does not exists for Angular
  4. For this:

    In the Angular environment.ts put those:

    export const environment = {

    production: false, //put also in the prod

    urlAPI:’/’

    }

    • In production: deliver AOT Angular compiled in the same folder with the .NET
    • This will ensure that , when you send the Angular AOT build with .NET Core WebAPI in the same site, it will work. NO CORS involved 😉

    • In development: This mean Angular ng server intercepting  calls

    Then create a file named proxy.conf.js and put this to redirect:

    const PROXY_CONFIG = [
        {
          context: [
              "/employees",
              "/api",                
          ],
          target: "http://<url to the .NET Core API>/",
          secure: false,
          "changeOrigin": true,
          "logLevel": "debug",
          ws: true
        }
    ]
    module.exports = PROXY_CONFIG;
    
    

    Then run:

    ng serve –proxy-config proxy.conf.js –open

  • Setting SignalR for Angular in development
  • See ws: true in previous proxy.conf.js ? That is all, if you run

    ng serve –proxy-config proxy.conf.js –open

    From unstructured data to application

    Imagine that you have this kind of texts:

    Alpert of Metz – 11th-century – France – Medieval writers
    Aimoin of Fleury – c. 960 – c. 1010 – France – Medieval writers
    Amulo Lugdunensis (Archbishop of Lyon) – 9th-century – France – Medieval writers
    Amulo Lugdunensis (Archbishop of Lyon) – 9th-century – France / Carolingian Empire – Medieval writers
    Andrew of Fleury – 11th-century – France – Medieval writers
    Angelomus of Luxeuil – 9th-century – Francia / France – Medieval writers

    Vitsentzos or Vikentios Kornaros or Vincenzo Cornaro – c. 1553 – c. 1614 – Kingdom of Candia / Crete / Greece – Renaissance

    Adrianus of Tyre – c. 113 – c. 193 – Greece / Roman Empire – Ancient & Classical writers

    How transform this unstrcutured data to make an application that search like in the picture below ( just the R from CRUD )?

    Detailing  the tools:

    1.  Transforming data: Excel + VBA – to parse from the text the name, country / countries , years period  movement and generate insert  /stored procedurees call

    2. Storing+ retrieving data: Sql Server – creating tables and stored procedures to insert / retrieving data

    3. Acessing data: .NET Core – to make WebAPI to export as WebAPI HTTP endpoints t

    4. Display data:

    5. Deploy:

    • RedfHat OpenShift to deploy site
    • Azure to have sql server on the web

    Hours or work ~ 20 . And hey, it works!

    .NET Core SignalR Hub+ Angular Observable

    TL;DR: Deliver all the table content continuously paginated to the browser with .NET Core and Angular


    Long Description:

    I was thinking that delivering paginating data is kind of lame. Why should I , for seeing the whole data, should keep pressing next page / or scrolling  down ? I understand that on the server it is necessary to do this – but on the client ?

    And I was thinking – what about Observables in Angular  , combined with SignalR ? Those observables could obtain data every time – and SignalR is pushing cotinously, until it arrives at the end of the data.

    Done with talking –  let’s show some code:

    We have an Employee classs

    public class Employee
        {
            public string Name { get; set; }
            public int Id { get; set; }
    
        }
    

    code

    and we are feeding with data in a DALEmployee

    public class DalEmployee
        {
            public int FindCountEmployees(string name)
            {
                return ((name ?? "").Length + 1) * 10;
            }
    
            public async Task<Employee[]> FindEmployee(int pageNumber, int pageSize, string name)
            {
                await Task.Delay((pageNumber + 1) * 1000);
                var ret = new Employee[pageSize];
                int startNumber = (pageNumber - 1) * pageSize;
                for (int i = 0; i < pageSize; i++)
                {
                    var e =new Employee();
                    e.Id = startNumber + i;
                    e.Name = e.Id + "employee ";
                    ret[i] = e;
                }
    
                return ret;
            }
        }
    

    We have SignalR that delivers continously the data via a Hub that is connected to an URL

    //do not forget  services.AddSignalR().AddJsonProtocol()  ;
                app.UseSignalR(routes =>
                {
                    routes.MapHub<MyHub>("/employees");
                })
    

    and delivers all data continuously

     public class MyHub: Hub
        {
           
            public override async Task OnConnectedAsync()
            {
                Console.WriteLine("!!!!connected");
                await Task.Delay(1000);
            }
            public ChannelReader<Employee[]> GetEmps(string name)
            {
                var channel = Channel.CreateUnbounded<Employee[]>();
                _ = WriteItems(channel.Writer, name); //it not awaits!
    
                return channel.Reader;
            }
    
            private async Task WriteItems(ChannelWriter<Employee[]> writer, string name)
            {
                var dal = new DalEmployee();
                var nr = dal.FindCountEmployees(name);
                int nrPages = 10;
                for (int i = 0; i < nr / nrPages; i++)
                {
                    var data = await dal.FindEmployee(i+1, nrPages, name);
                    await writer.WriteAsync(data);
                }
    
                writer.TryComplete();            
            }
    

    And this is all that is required on the .NET Core side

    For the Angular Part

    We have a hubconnectionbuilder that connect to the hub

    export class MydataService {
    
      h:HubConnection;
      constructor(private http: HttpClient) { 
        this.h= new HubConnectionBuilder()
          .withUrl(environment.urlAPI + "/employees")
          .withHubProtocol(new JsonHubProtocol())
          //.withHubProtocol(new MessagePackHubProtocol())
          .build();
          window.alert('start');
        this.h.start()
        .catch((t) => window.alert(1));
      }
      
      
    }
    

    and a observable that returns the values

    
    
      public getAllEmpsStream(name:string): Observable<Employee[]>{
        
        const subject = new Subject<Employee[]>();
        this.h.stream<Employee[]>("GetEmps",name).subscribe(subject);
        return subject.asObservable();
    
      }
    
    

    The code on the component is aggregating the values into an array

    findEmployees(){
        this.load=true;
        this.service
          
          .getAllEmpsStream(this.nameEmp)
          //.getEmps(this.nameEmp)
          .pipe(finalize(() => this.load=false))
          .subscribe(it  => {
            
            //window.alert(it.length);
            this.emp.push(...it);
    
          });
    
      }
    

    And that is all. All the values are returned page after page without the need of human intervention…

    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.