Oct 26, 2018

RePost: .NET Architecture guides - DDD, CQRS, Clean, Onion etc.



Set of really good (and free) e-books related to modern and distributed architectures:

Here is a interesting component to investigate (by the author of Automapper):



Here is a list of recommended code samples to look and digest:

Metrics:
https://www.app-metrics.io/






Oct 19, 2018

ASP.NET Core 2.1 - NuGet - Blocked by project issue - AspnetCore.App

Some NuGet packages are added by default as part of framework.

https://docs.microsoft.com/en-us/nuget/tools/package-manager-ui#updating-a-package

For example : Microsoft.ASPNetCore.App.

If you get error that you can not update them to newest version with something like:
"Blocked by project. Update SDK"
; this could help.

Opet CSPROJ file and manually add this line under <PropertyGroup>:

<RuntimeFrameworkVersion>2.1.4</RuntimeFrameworkVersion>



Oct 15, 2018

IoC - Dependecy injection - StructureMap - ASP.NET Core 2.1 - Using factory to inject all type implementations


There are different implementations of IApplicationContext:
- MyContext1
- MyContext2
Also in future we may add new implementations.
We want to use this context in generic class repository like this:

class MyRepository<T, C> : IRepository<T, C> where T : Entity<T> where C : IApplicationContext

So far everything is straightforward. Repository will know two dependencies - entity and repository.
Consumer classes will reference repository like this:

private IRepository<MyEntity, MyContext1> myRepo1;

But how to obtain instance of MyContext1 inside our MyRepository ?

We could write something like:

var context = new C();

It would work but we could not write unit tests for such class since we create explicit instance inside our method which breaks dependecy injection effort.

Alternative is quite elegant and supported by StructureMap IoC container.

First step is to explicitly scan for all instances of our context like this:

Scan(scan =>
{
scan.AssembliesFromApplicationBaseDirectory();
scan.WithDefaultConventions();
scan.AddAllTypesOf<IApplicationContext>();
});

Then comes the magic touch :)
We create new Factory class. 

Array of contexts is populated with all known implementations of IApplicationContext.

And lastly the requested one is selected from that list through simple generic method:

public class ApplicationContextFactory : IApplicationContextFactory

{

private readonly IApplicationContext[] _applicationContexts;

public ApplicationContextFactory(IApplicationContext[] applicationContexts)
{
_applicationContexts = applicationContexts ?? throw new ArgumentNullException(nameof(applicationContexts));

}

public IApplicationContext GetContext<T>() where T : IApplicationContext
{

return _applicationContexts.SingleOrDefault(c => c is T);

}
}

Factory is then used in our repository generic class to resolve in simple way our instance required by type that called repository:

_applicationContext = _applicationContextFactory.GetContext<C>();

Oct 5, 2018

JQuery Validation on dynamic form (ASP.NET MVC unobtrusive)

Update

Just add this line in your injected form or in success callback:

              $.validator.unobtrusive.parse("form");              

Bellow code is not needed but it may be useful for its context...

For some reason I've could only make it work on explicit input event binding.

    $(document).off('change', 'input', onInputChange);
        $(document).on('change', 'input', onInputChange);
 function onInputChange() {   
        //Manually initiate unobtrusive validation so error messages are shown
        $(this).closest("form").valid();     
    }

If you are saving using Ajax then prevent saving something like this:

    function SaveItemCallback(e) {
        e.preventDefault();
        if ($(this).closest('form').valid() === false) {
            return;
        }
 var postBody = $(this).closest('form').serialize();
        $.post(options.urlSave, postBody, function (id) {
            loadDetails(id);
        })
            .fail(function () {
                toastr.error(myErrorText);
            });