Wednesday, October 14, 2020

How to show Serilog log in UI

What ? Well I tried to develop simple UI test application by which a tried to manually test my communication classes .

Of course there was idea to show log messages, errors or information messages, in UI, in this case in WPF app . 

But how  ?

So I created a field in UI, lately listBox, but how to fill that field.

Fortunately there is a simple solution , and that is sink "Observers".

_logger = new LoggerConfiguration()
    .WriteTo.Observers(events => events
       .Do(evt => {
           LogTextAppend(Environment.NewLine);
           LogTextAppend(evt.Timestamp.ToString());
           LogTextAppend(": ");
           LogTextAppend(evt.Level.ToString());
           LogTextAppend(": ");
           try
           {
               LogTextAppend(string.Format(evt.MessageTemplate.Text,
                      evt.Properties.ToArray()));
           }
           catch
           {
               LogTextAppend(evt.MessageTemplate.Text);
           }
           LogTextAppend(Environment.NewLine);
           if (!(evt.Exception is null))
           {
               LogTextAppend(JsonConvert.SerializeObject(evt.Exception));
               LogTextAppend(Environment.NewLine);
           }
       })
    .Subscribe())
    .CreateLogger();

Of course it can by simpler or more complicated, but that is up to you.

Just use nuget Serilog.Sinks.Observable


Saturday, August 17, 2019

Another LoggerWrapper

So another logger wrapper ...

In  I was working on project which should also provide library for third party developers.
And there was logging ... So main problem was we had been used an version of Log4Net and another team has been using another version ...
So we recognized that library version lock problem.

First solution was to hide our version by Costura Fody, which was not working very well, and then ... then there was more difficult solution to use reflection.

And here is : AnotherLoggerWrapper

Simple idea is that there is an interface similar to Log4Net, with some implementations, which you can use in your project, and if somebody would like to use  your library then he can provide an object which then will be "investigated" by reflection, if it is compatible with Log4Net common interface, and then will be used. Used means - delegates will be produced, so it is not so slow.

There are examples in unit tests of GitHub project LoggerWrapper.

Example - how to use :

            var logger = LoggerWrapper.CreateFromILogLikeObject(loggerMock.Object);
            logger.Info(
"testMessage");1. How delegate is created:

Example - how delegates are created:

1. MethodInfo
        private static MethodInfo GetWriteMessageMethodInfo(MethodInfo[] methods, String methodName)
        {
           
var specificMethods = from mi in methods
                                  let p = mi.GetParameters()
                                 
where p.Length == 1
                                        && (p[
0].ParameterType == typeof(object) || p[0].ParameterType == typeof(string))
                                        && mi.Name == methodName
                                        && mi.IsStatic ==
false
                                        && mi.IsPublic
                                 
select mi;
           
var specificMethodsArray = specificMethods.ToArray();
           
if (specificMethodsArray.Count() == 1)
            {
               
return specificMethodsArray[0];
            }
           
return null;
        } 2. Delegate from method info         private static LogMethods.WriteObject GetWriteMessageMethod(MethodInfo methodInfo, Object instance)
        {
            LogMethods.WriteObject method =
null;
           
if (methodInfo != null)
            {
                method = (LogMethods.WriteObject) Delegate.CreateDelegate(
typeof (LogMethods.WriteObject), instance, methodInfo);
            }

           
return method;
        } I also enjoyed development of unit tests of this project, so whole project is just fun ... Enjoy !

Monday, February 4, 2019

How to update database from multiple DB projects

Database project which is available in Visual Studio, is very helpful. You can specify schema, tables, vies, develop procedures or specify other objects, everything is versioned ... and also there is build which will help you with mistakes.
Nice.

But how to update real database ?

From Visual Studio you can use "schema compare" tool which will graphically show you differences and then is able to generate SQL update script. Of course sometime it is not enough, because you may want to perform some data transformation , or add an column in the middle in example, but for simple scenarios it is good enough.

But you can have multiple database projects, like per schema, and  schema compare "scenario"  is not very comfortable then.

So little automation is needed.

Database project "end product" is not an dll or exe but dacpac file, and there is command line utility which can use dacpac file to update real database.

sqlpackage.exe is offered by Microsoft, and can create SQL script, or bacpac, or report,or can publish dacpac file.

"Publish" mean that actual DBis compared with definition from dacpac, like "Schema compare" from Visual Studio, the SQL update script is prepared and started.
Example:
sqlpackage.exe /Action:Publish /SourceFile:"myDB.dacpac" /TargetDatabaseName:MyDB /TargetServerName:MyDBServer /TargetUser:MyUser /TargetPassword:MyUserPassword

When you have multiple DB projects per schema then there is problem that normal schema compare will also notice that in real DB there are objects which are not present in dacpac and therefore will try to drop them in SQL update script. Therefore we should add to parameters /p:DropObjectsNotInSource=false.
Also will be nice to have one command to update database in once.

My solution:
1. Collect all dacpacfiles in one folder.
Just create and common folder and add to all projects in post build event something like:
copy $(ProjectDir)bin\release $(SolutionDir)Setup\DB    /Y
exit 0
- exit 0 is required because copy will endwith exit 1 which will cause build failed error for msbuild
2. create bat or ps which will start Sqlpackage.exe for all dacpac files
like:
for %%f in (*.dacpac) do (
    sqlpackage.exe /Action:Publish /SourceFile:"%%~nf.dacpac" /p:DropObjectsNotInSource=false /TargetDatabaseName:%2 /TargetServerName:%1 /TargetUser:%3 /TargetPassword:%4 
)

Thanks for you attention !


Wednesday, December 26, 2018

Tell mi why ...

It is Christmas Time ! :-)
Families are organizing  "meetings"... talking about everything ... also about programing.

But sometime it is ... why to hell somebody will create a method with 16 parameters when 9 of them are optional ? Why to hell ? Probably it was not done in one shot, so multiple times somebody added there a parameter , but why ? It is the worst multiparameter method I ever saw ... and then it become ... my nephew, younger then 30 , told me " I saw ones a method with 22 parameters and just one was mandatory".

Please don't do it. It is Christmas Time ...

Wednesday, July 26, 2017

Linq – Distinct - fun ?


Linq is nice. Usable. Readable. But … Distinct.
In short. There is no appropriate distinct in Linq.
What I mean “Appropriate” ?. Something like myList.Distinc(x=>x.id).
And there is nothing like that.

Possible solutions:

1. Group by

var queryLastNames =
        from student in students
        group student by student.LastName into newGroup
        orderby newGroup.Key
        select newGroup;

2. Morelinq library

  • it is a Nuget package
  • there is: 
    • myList.DistincBy(x=>x.id)
    • or myList.DistinctBy(x=>new {x.Id1,x.Id2,x.Id3)
  • it is from year 2009 … and it is still not implemented in Linq …
  • Thank you Pranay Rana

3. You can create your own TryToDictionary method


  private static Dictionary<T, K> TryToDictionary<T,K>(
         Func<K,T> getId,
         IEnumerable<K> list)
        {
            var result = new Dictionary<T, K>();
            foreach (var item in list)
            {
                if (result.ContainsKey(getId(item))) continue;
                result.Add(getId(item), item);
            }

            return result;
        }

        private static List<K> TryToUniqueList<T, K>(Func<K, T> getId, IEnumerable<K> list)
        {
            return TryToDictionary<T,K>(getId,list).Select(x => x.Value).ToList();
        }

4. Use original distinct with IEqualityComparer<T>

4.1 Implement IEqualityComparer<T>

.. Just if You really need one ...

4.2 But You can create a lambda version ! :-)

.. thank you Ruben Bartelink and Stackowerflow !

       public class LambdaEqualityComparer<T> : IEqualityComparer<T>
        {
            readonly Func<T, T, bool> _comparer;
            readonly Func<T, int> _hash;

            public LambdaEqualityComparer(Func<T, T, bool> comparer)
                : this(comparer, t => 0)
            {
            }

            public LambdaEqualityComparer(Func<T, T, bool> comparer, Func<T, int> hash)
            {
                _comparer = comparer;
                _hash = hash;
            }

            public bool Equals(T x, T y)
            {
                return _comparer(x, y);
            }

            public int GetHashCode(T obj)
            {
                return _hash(obj);
            }
        }

then you can use it like this

myList.Distinct(new LambdaEqualityComparer<MyClass>((x,y)=>x.Property1.Equals(y.Property1)));


4.2.3 You can  also create it as extension method ...

Sunday, July 2, 2017

Shelveset in TFS , git and subverson

First. What is shelveset.
In TFS ( Team Foundation Server from Microsoft) you can store yours changes on server for later use. You can specify the name, but also your developer name will be stored with that change. You can also specify if changes will be preserved on your pc (aka workspace/repository) or not.
Created shelveset you can  "unshelve" and use it whenever you need on the original pc, but, you can use that shelveset on another computer if needed , like when you are in another office, on a business trip, or simply when your pc is broken somehow, and also another colleague, whenever is located, can unshelve your shelveset.

So it is  quite useful.

But what about git ? Is there something similar ?

Yes, and no :-)
Git have a stash. You can stash , there is command for that, your changes, which then will be stored in "stash part" of git repository. But usually you are using local repository, so when you should use another computer you are lost. Of course you can commit and push your changes to remote/origin repository, so if you have a branch on remote repository , you will got something similar as TFS shelveset. There is also possibility to migrate stash from one repository to another, but I never tried that successfully ...
But there is advantage in comparison to TFS. TFS, it is a shame, is storing shelveset with branch information. So you can unshelve shelveset just into the same branch ! Crazy. Of course there is solution, but it is command line based ... Git stash can be "unstashed" into anyone branch.

But what about subversion (svn) ?
Yes there is something. A patch. You can create patch of your changes. It is one file which you can store whenever you like. If you will crate a folder under your subversion repository, you can also upload/commit your patch file into subversion  repository and then you or anybody else can use it .

Also there are other versioning systems like Mercurial but I never used them ;-)
Maybe in the future.

Wednesday, April 19, 2017

Git for TFS users - a cheat sheet

It was tough.

When I started to use Git, because now nearby everybody is using Git, it was tough. Really tough.
Imagine transition from Visual Studio 2015 & TFS to Eclipse, Jira, Jenkins, Gerrit and Git (command line).

What I saw was that there are developers which have no other experience than Git. And Gerrit, And Jira. And Jenkins.
So those were satisfied.
I was not.

But another project arrived, with Jira, Jenkins, GitLab, Artifactory and ... with msbuild and Visual Studio 2015, and I was not lost :-)
So today I can say it is good to have experience with multiple development environments.

But to simplify start for TFS/Visual Studio developers, which are trying to use Git, I prepared a presentation and this "cheat sheet" which is improved version of this one.


TFS Version Control
Git
Workspace
Repository (aka. “Repo”)
Get Latest  (First time)
Clone
Get Latest (After first time)
Pull
Check in
Commit + Push
Check out
There is no lock ! no checkout !
Branch
Branch
Merge
Merge
Shelve
Stash - just local ! (on local machine ...)
Label
Tag
Included changes
Staged
Excluded changes
not staged

Also you can check may previous post about three common "scenarios" which are used in Git environments for "check-out - check-in"