Create a new exception–add fields and/or properties

This post is not about why we need custom exception (https://blogs.msdn.microsoft.com/jaredpar/2008/10/20/custom-exceptions-when-should-you-create-them/ ) . It is (more a rant ) about a specific  item in best practices in Exceptions( https://docs.microsoft.com/en-us/dotnet/standard/exceptions/best-practices-for-exceptions )

It says:

In custom exceptions, provide additional properties as needed

Provide additional properties for an exception (in addition to the custom message string) only when there’s a programmatic scenario where the additional information is useful. For example, the FileNotFoundExceptionprovides the FileName property.

What I want to add : In EVERY exception that you create in code, DEFINE a custom field. It  is useless without !

Why this rant ? In Stankins I have to intercept KeyNotFoundException  and I want to find the Key that was not found ( problem with some dictionary ) to provide it (Yes, it is a flawed design – but this is not the point here) . The problem was the definition:

public class KeyNotFoundException : SystemException, ISerializable
{

public KeyNotFoundException();

public KeyNotFoundException(string message);

public KeyNotFoundException(string message, Exception innerException);

protected KeyNotFoundException(SerializationInfo info, StreamingContext context);
}

See the problem ? No way to find WHAT is the Key that was not found. So I ended up with this code:

name =innerKeyEx.Message;
// The given key 'nameColumn' was not present in the dictionary.
var first=name.IndexOf("'");
var last= name.IndexOf("'",first+1);
name= name.Substring(first+1,last-first-1);

Moral of the post ? Do NOT define a custom Exception without defining a field / property inside!

Dynamic loading controllers in .NET Core

I needed to load dynamically some controllers to the Stankins application .Dynamic like in – written in some text file, then loading them, The best reference was https://www.strathweb.com/2018/04/generic-and-dynamically-generated-controllers-in-asp-net-core-mvc/ . But it was not enough : what I wanted is to write the controller in some text file and compile and load them.

First problem ; What about the dll’s to be loaded  ?

I ended up with this code :

var refs=new List<MetadataReference>();
var ourRefs=Assembly.GetEntryAssembly().GetReferencedAssemblies();

foreach(var item in ourRefs)
{
	var ass=Assembly.Load(item);
	refs.Add(MetadataReference.CreateFromFile(ass.Location));
}
refs.Add(MetadataReference.CreateFromFile(typeof(Attribute).Assembly.Location));
//MetadataReference NetStandard = MetadataReference.CreateFromFile(Assembly.Load("netstandard, Version=2.0.0.0").Location);
MetadataReference NetStandard = MetadataReference.CreateFromFile(Assembly.Load("netstandard").Location);
refs.Add(NetStandard);
refs.Add(MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location) );             

Second problem: where to put the errors ? The simplest option ( not the best one) is to put as comments to the end of the file – at reloading I will find them and correct

using (var ms = new MemoryStream())
{
	var res = compilation.Emit(ms);

	if (!res.Success)
	{           
		string diag=string.Join(Environment.NewLine, res.Diagnostics.Select(it=>it.ToString()));
		File.AppendAllText(fileName,"/*"+diag+"*/");
		return null;
	}
}

( Better – to display the error inline…)

Third problem: The controlers are loaded at initial step of configuring .NET MVC Core 2.x , not later. The assembly loader /unloader will come as a feature at .NET Core 3 – so not yet. I figure up that the best solution is to re-load the application

static CancellationTokenSource cancel ;
        static bool InternalRequestRestart;
        public async static Task Main(string[] args)
        {
            do{
                InternalRequestRestart=false;
                cancel= new CancellationTokenSource();
                await CreateWebHostBuilder(args).Build().RunAsync(cancel.Token);
                await Task.Delay(10);//just waiting some time
                Console.WriteLine("restarting");
            }while(InternalRequestRestart);

        }
        public static void Shutdown()
        {
            InternalRequestRestart=true;
            cancel.Cancel();
        }

 

You can find the code source for loading the controllers at https://github.com/ignatandrei/stankins/blob/master/stankinsv2/solution/StankinsV2/StankinsData/GenericControllerFeatureProvider.cs

You can find the code source for restarting the application at https://github.com/ignatandrei/stankins/blob/master/stankinsv2/solution/StankinsV2/StankinsData/Program.cs

You can test the code at https://azurestankins.azurewebsites.net/receiveData ( add a new controller , hit save and then access the route – or swagger at https://azurestankins.azurewebsites.net/swagger/index.html

– or you can try with Docker with

( for linux containers)

docker run -p 5000:5000 ignatandrei/stankins_linux

( for windows containers)

docker run -p 5000:5000 ignatandrei/stankins_linux

( restart docker if any problems)

and access http://localhost:5000/receiveData

That’s all 😉

[Presentation]Angular + .NET Core => Applications for Mobile, Web and Desktop – Andrei Ignat

I was invited at http://apexvox.net/#schedule to present ] Angular + .NET Core => Applications for Mobile, Web and Desktop

It was very exciting to find so many people interested in .NET . And it was good to re-see old friends, like http://vunvulearadu.blogspot.com/2019/03/post-event-apexvox-cluj-napoca-2019.html , Daniel Costea, Ciprian Jichici and to make new ones

You can find the code and the presentation at https://github.com/ignatandrei/angNetCoreDemo/ .
If you need help, please contact me directly

Identify version for application and components for Backend(.NET Core) and FrontEnd(Angular)–part 3- FrontEnd

Part1 : Introduction and Concepts

Part 2: Obtaining BackEnd Components Version

Part 3: Obtaining FrontEnd Component Version and Final Library

Live Demo 

NPM component
Copy paste NET code

Identifying the version of Angular components that we are using is a bit tricky. The package.json is having, by default, components using version “greater than”. More than that , after AOT compiling it remains no evidence of the original software used. However, there is a helper  npm-shrinkwrap : this will generate a npm-shrinkwrap.json file that fixes the versioning.

So the second part is to request the .NET version and the npm-shrinkwrap.json  file content with Angular front-end

For this we have a class that takes , by Dependency Injection, the HTTP Client and request versions from .NET Core and Angular:

 

export class VersionsNetcoreAngularService {

constructor(private http: HttpClient) {

const self = this;

}

public FVS(): Observable<FileVersionInfo[]> {

console.log('get fvs');

return this.http.get<FileVersionInfo[]>('api/Utils/GetVersions');

}

public FVSAngular(): Observable<FVSAng[]> {

console.log('get fvs angular');

return this.http.get('npm-shrinkwrap.json').pipe

(

switchMap(data => {

const ret = data as PackageJSONVersion ;

const d = ret.dependencies;

const arr = new Array<FVSAng>();

let f = new FVSAng();

f.name = ret.name;

f.fileVersion = ret.version;

arr.push(f);

for (const key of Array.from( Object.keys(d)) ) {

const dep = d[key] as Dependency;

if (dep.dev) {

continue;

}

f = new FVSAng();

f.fileVersion = dep.version;

f.name = key;

arr.push(f);

}

return of(arr);



})

);

}

The rest is history – just display the version in a HTML GUI.

Identify version for application and components for Backend(.NET Core) and FrontEnd(Angular)–part 2- backend

Part1 : Introduction and Concepts

Part 2: Obtaining BackEnd Components Version

Part 3: Obtaining FrontEnd Component Version and Final Library

Live Demo 

NPM component
Copy paste NET code

Identifying the version of the dll’s  used on the backend is fairly simple. All we need is to iterate into the current directory and find the version of the dlls.  It is just a simple controller that receives via Dependency Injection the path to the current directory. It is no harder than that code:

 

[HttpGet]

public FileVersionInfo[] GetVersions([FromServices] IHostingEnvironment hosting)

{

var dirPath = hosting.ContentRootPath;

var ret = new List&lt;FileVersionInfo&gt;();

var files = Directory.EnumerateFiles(dirPath, "*.dll", SearchOption.AllDirectories).Union(Directory.EnumerateFiles(dirPath, "*.exe", SearchOption.AllDirectories));



foreach (string item in files)

{

try

{

var info = FileVersionInfo.GetVersionInfo(item);

ret.Add(info);

&nbsp;

}

catch (Exception)

{

//TODO: log

}

}

return ret.ToArray();

}

}

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.