.
Anmeldung | Registrieren | Hilfe

.NET-Blogs Archiv November 2015

VS 2015 Update 1, TypeScript 1.7 and some more

30.11.2015 17:00:00 | Jürgen Gutsch

Yesterday, it was something like an announcement day. Let's have a look to the news from Redmond:

Visual Studio 2015 Update 1

This is what the most of us are waiting for: Microsoft released the Update 1 of Visual Studio 2015. There many improvements added to the IDE, with the debugging and navigation. See the detailed description in this blog posts:

TFS 2015 Update 1

Brian Harry announced the availability of TFS 2015 Update 1, which includes a lot of new things and a few bug fixes:

This update is also available for TFS 2015 Express.

.NET Framework 4.6.1

Along with the Update 1 of Visual Studio 2015, Microsoft released .NET 4.6.1 with some improvements and big fixes in WPF and SQL Server connectivity, RyuJIT, GC and WCF:

TypeScript 1.7

Also the TypeSript team announced a new version. They highlighted to support for async and aweit in the new version 1.7:

Azure SDK 2.8.1 for .NET

Another thing what was released yesterday, is the Azure SDK 2.8.1 for .NET. See Brady Gasters blog post for more details about it:

View Components in ASP.NET 5

25.11.2015 00:16:00 | Jürgen Gutsch

Eine der schönsten Neuerungen in ASP.NET 5 sind die View Commponents. Diese sind eine Art Mini MVC innerhalb der MVC Applikation die sich allerdings einbinden lassen wie PartialViews. Also Partielle Views mit eigenem Controller. In etwa Vergleichbar mit User Controls in ASP.NET Webforms. Anwendungsfälle wären wiederkehrende Elemente einer Website oder eins Blogs, die nichts direkt mit dem eigentlichen Inhalt zu tun haben. Also alles was nicht unbedingt über die aktuelle Controller Action kommen muss. Nehmen wir als Beispiel das Blog, das außer die Artikelliste und den Artikel noch mehr enthält, wie z. B: eine Navigation, Tag-Liste, Linkliste, Archivübersicht, etc. Das alles kann man über die aktuelle Controller Action ermitteln und an die View geben. Allerdings muss das in jeder View immer wieder gemacht werden.

Schöner wäre es, wenn sich die aktuellen Actions nur mit dem befassen was ihre primäre Aufgabe ist: Das ermitteln und zurückgeben eines Artikels, oder das ermitteln und zurückgeben einer Artikelliste. Alle anderen genannten Teile des Blogs könnten doch irgendwo anders passieren, wo es die Actions nicht mit Logik zumüllt für die die Actions nicht zuständig sein sollten.

Genau hier kommen die View Components ins Spiel:

Zuerst wird eine Klasse erstellt, die von ViewComponent ableitet und ViewComponent als Sufix haben sollte, z. B. TopTagsViewComponent:

public class TopTagsViewComponent : ViewComponent
{
    private readonly ITagService _tagService;

    public RecommendedProductsViewComponent(ITagService tagService)
    {
        _tagService = tagService;
    }

    public IViewComponentResult Invoke()
    {
         var tags = _tagService.LoadTopTags();
         var models = tags.Select(=>
            new TagViewModel
            {
                Id = tag.Id,
                Name = tag.Name
            });
        return View(models);
    }
}

Die Methode Invoke entspricht der Action in einem regulären Controller, an deren Ende eine View erzeugt und zurückgegeben wird. Der TagService der hier genutzt wird kann per IoC in die ViewComponent hineingegeben werden. Da IoC wirklich überall zur Verfügung steht, kann auf jede Quelle zugegriffen werden, auf die eine regulärer Controller zugreift.

Die View ist eine ganz normale Razor View:

@model IEnumerable<WebApp1.ViewComponents.TagViewModel>

@if (Model.Any())
{
    < ul>
        @foreach (var tag in Tags)
        {
            <li>
                [@tag.Id] @tag.Name
            </li>
        }
    </ul>
}

Einzig der Ort an dem diese View abgelegt werden muss ist ein wenig speziell. Die Views werden unter Shared in einem Ordner Components abgelegt. Dort wiederum in einem Unterordner, der dem Namen der ViewComponent ohne dessen Sufix entspricht. Unsere ViewComponent View liegt also unter /Shared/Components/TopTags/Default.aspx

Der Standardname ist Default.aspx. Es kann aber auch jeder beliebige andere Name verwendet werden, wenn dieser in der Methode Invoke angegeben wird:

return View("TheNicerName", models);

Auf die Art könnte man auch innerhalb der ViewComponent daas Template wechseln, wenn es erforderlich sein sollte.

Die oben beschriebene Komponente wird dann ganz einfach, fast ähnlich wie eine PartialView eingebunden:

@Component.Invoke("ToTags");

Argumente übergeben

Interessant werden ViewComponents auch, wenn man Argumente übergibt. Angenommen wir möchten die Zahl der Tags anpassen, je nachdem, wo wir die Liste einsetzen wollen.

Wir erweitern die Methode Invoke einfach um ein Argument:

public IViewComponentResult Invoke(int count)     

    var tags = _tagService.LoadTopTags().Take(count);     
    var models = tags.Select(tag =>
        new TagViewModel 
        { 
            Id = tag.Id, 
            Name = tag.Name 
        }); 
     return View(models); 
}

Und rufen die Methode Invoke auch einfach mit diesem zusätzlichen Argument auf:

@Component.Invoke("ToTags", 10);

Asynchrone ViewComponents

Um Asynchrone Views besser zu unterstützen, kann statt der synchronen Methode Invoke auch eine asynchrone Methode geschrieben werden:

public async Task<IViewComponentResult> InvokeAsync(int count)     

    var tags = await _tagService.LoadTopTags();     
    var models = tags.Select(=>
        new TagViewModel 
        { 
            Id = tag.Id, 
            Name = tag.Name 
        }).Take(count); 
     return View(models); 
}

Bei der Nutzung muss dann await genutzt werden:

@await Component.InvokeAsync("ToTags", 10);

View Components in ASP.​NET 5

24.11.2015 17:00:00 | Jürgen Gutsch

One of the nicest new features in ASP.NET 5 is the ViewComponent. This is a kind of a 'mini MVC' inside the MVC application which can be used like partial Views. ViewComponents are like partial Views with an own controller, almost comparable with a UserControl in ASP.NET WebForms.

Use cases are multiple reused components of a web application. That means all things that must not be managed by the current controller action. Let's use a Blog as an example, which has some more elements like menus, tag lists, link lists, archive overviews, etc. The data of these elements can be passed via the current actions to the view, but this needs to be done in every single action and produces a lot of duplicate code.

It would be nice if the controller actions only have to do one single task: fetching and passing blog posts to the view. All the other things should be done on other locations, to not mess up the controller actions.

That's where the ViewComponents entering the stage.

Let me show you how ViewCompnents look like

First we need to create a simple class which derives from ViewComponent and which needs to have "ViewCompoennt" as a sufix. E. g. "Top20TagsViewComponent":

public class Top20TagsViewComponent : ViewComponent 
{ 
    private readonly ITagService _tagService; 

    public Top20TagsViewComponent(ITagService tagService) 
    { 
        _tagService = tagService; 
    } 

    public IViewComponentResult Invoke() 
    { 
         var tags = _tagService.LoadTop20Tags(); 
         var models = tags.Select( 
            new TagViewModel 
            { 
                Id = tag.Id, 
                Name = tag.Name 
            }); 
        return View(models); 
    } 
}

The method Invoke almost looks like a Action in a usual Controller, which creates and returns a View. The used TagService is injected with the default IoC. Because is available everywhere in ASP.NET 5, you can access everything what accessible with a usual Controller.

The View is pretty common:

@model IEnumerable<DotNetFn.ViewComponents.TagViewModel>

@if (Model.Any()) 
{ 
	<ul> 
        @foreach (var tag in Tags) 
        { 
            <li> 
                [@tag.Id] @tag.Name 
            </li> 
        } 
    </ul> 
}

Only the location where the View needs to be saved is a bit special. You need to save the default View with the name Default.cshtml in a folder, which is named like the ViewComponent without the suffix inside /Views/Shared/Components/ Our ViewComponent is stored in /Shared/Components/Top20Tags/Default.cshtml

The default name is Default.cshtml, but you can use any other name, if you pass that name to the View:

return View("TheNicerName", models);

With this you are able to switch the Templates inside the ViewComponent, if it is needed.

The described Component will be used almost as a partial View:

@Component.Invoke("TopTags");

Passing arguments

A very interesting thing is to pass arguments to a ViewComponent. Maybe you want to change the number of Tags to display, depending on where we want to use this Component.

We only need to extend the Invoke method with one ore more arguments:

public IViewComponentResult Invoke(int count)     
{ 
    var tags = _tagService.LoadTopTags().Take(count);     
    var models = tags.Select(tag => 
        new TagViewModel 
        { 
            Id = tag.Id, 
            Name = tag.Name 
        }); 
     return View(models); 
} 

Now we able to call the ViewComponent with that additional argument:

@Component.Invoke("TopTags", 10);

Asynchronous ViewComponents

To support asynchronous Views, we can also use a asynchronous Invoke method instead:

public async Task<IViewComponentResult> InvokeAsync(int count)     
{ 
    var tags = await _tagService.LoadTopTags();     
    var models = tags.Select(=> 
        new TagViewModel 
        { 
            Id = tag.Id, 
            Name = tag.Name 
        }).Take(count); 
     return View(models); 
} 

We only need to use await in the View to use this InvokeAsync:

@await Component.InvokeAsync("TopTags", 10);

ASP.NET 5 RC1 wurde veröffentlicht

23.11.2015 00:27:00 | Jürgen Gutsch

 

November 2015 war die schwammige Angabe für das RC1 und seit letzter Woche Mittwoch ist es soweit. RC1 ist draußen inklusive Go-Live Lizenz, was so viel heißt, dass diese Version produktiv genutzt werden kann und dieses auch von Microsoft supportet wird.

image

Mit ASP.NET 5 kommen auch das neue .NET Core 5 und das Entity Framework 7 als Release Candidate raus.

.NET Core und ASP.NET 5 bringt gegenüber der Beta 8 nicht viel neues. Es wurde eher im Hintergrund sehr viel optimiert und gefixt. Auch das Tooling im Visual Studio 2015 wurde verbesset. So gibt es jetzt unter anderem eine Package Manager UI für Bower, die ähnlich aufgebaut ist wie die UI von NuGet und der NuGet Package Manger UI werden Packages mit Scripts und ähnlichem, die mit Bower geholt werden sollten als inkompatibel markiert und mit dem Hinweis versehen, doch die Packages mit Bower zu laden.

Mehr Details zur aktuellen Version gibt es von Jeffrey T. Fritz unter http://blogs.msdn.com/b/webdev/archieve/2015/11/18/announcung-asp-net-5-release-candidate-1.aspx

Wie man auf die aktuelle Version aktualisiert, links zu Installern und weitere Anleitungen sind in der Dokumentation unter folgender Adresse zu finden: https://docs.asp.net/en/latest/getting-started/installing-on-windows.html

Moving .NET libraries to .NET Core

19.11.2015 17:00:00 | Jürgen Gutsch

At the MVP Summit 2015 Albert Weinert told us that ASP.NET has a huge problem: Almost all of our favorite tools are not usable with .NET Core. Many unit test frameworks, IoC containers, almost all mocking frameworks will not work with .NET Core and needs to be moved to DNX libraries to get portable. Additionally almost all mocking frameworks are based on the Castle.Core library, which also needs to be moved to be portable.

Currently I'm working at LightCore to make it compatible to .NET Core, to make the world a little better ;) Hopefully. This needs some steps to do. More details are in a separate blog post about LightCore 2.0. Because the unit tests of LightCore don't use mocking tools this was easier than expected.

With this post I want to tell you, what you need to do to move your library to .NET Core. I will use the 'Simple Object Store' to make a step by step tutorial. At the end my open source library will be compatible with .NET Core :)

But why should I do this? Is this future proof? Does the effort make sense?

At first I need to know that DNX projects (that's the name of the .NET Core libraries) are a kind of portable libraries. The only difference is that portable class libraries building a single assembly and DNX projects creating a NuGet package. All the other stuff is equal. This means the the libraries are compatible to many different platforms and frameworks. If I build a DNX library, I can use this library in .NET Core, .NET Framework, UWP and Mono. This should answer the questions above.

The current state of the Simple Object Store

Currently the solution includes many framework specific projects with linked source files to build against different Framework versions. This needs to be replaced with one single DNX project. I don't want to support frameworks lower than .NET 4.0 (Please tell me if you need a build for a lower version than 4.0.)

That means I have four projects for the SimpleObjectStore and the same number of projects for the AzureStorageProviders. And I have two test projects, one for the main library and one for the providers library.

The goal is to have four different libraries instead of 10.

Step 1: Convert the main library

In the Solution I remove the main library and create a new DNX library with the same name. I need to rename old the project folder before. I Add all the existing code files into the new DNX project After that I need to add the frameworks I want to support and to update the dependencies in the project.json to get the project building.

Step 2: Convert the providers library

To get the AzureStorageProviders library running on .NET Core I have to do exactly the same for as for the main library. Additionally I need to add a reference to the main library. To get the right reference I have to add a dependency to the main project without a version number. (If I would add a version number, the build look for an existing NuGet package on nuget.org)

Step 3: Converting the unit test projects

Currently I'm using NUnit to test the SimpleObjectStore. I need to decide whether to change to Xunit or to use the new NUnit 3.0.0 portable build.

I'll give the new NUnit a try. In the tutorial about using the portable build, they show the way to use a DNX console application to create a test project. I disagree with that. I would like to have a separate DNX console application as a NUnit runner. This should work in the same way as the Xunit runner. I just created it in a separate project.

Because I have the separate runner I can use the same way as in Step 1 to create DNX libraries for the test projects. Additionally I add a reference to the NUnit runner and add a command called test, which runs the Runner and passes the current test library.

"commands": {
	"test": "nunit.runner.dnx"
}

(I use the NUnit namespace because I want to contribute this runner to the NUnit project. I use it here as a kind of dog-fooding to test the runner.)

If this is done, we need to get this projects compiled. I did this, by try and error, building, fixing, building, fixing, and so on... The old NUnit API is almost equal to the new NUnit 3.0.0 API and there is less to do than expected.

Step 4: Add a CI server

To get this compiled and published I also use AppVeyor as a favorite CI server i the same way as written in the last post about Building LightCore 2.0

Final words

Hopefully this post will help you to make your libraries running on .NET Core and any other platform and framework. As you can see this isn't really a big deal. You need to know some small things about DNX libraries to create packages which are targeting as many platforms as possible. From my point of view, with the new possibilities given by .NET Core it is really important to get ready to go the same way as Microsoft. Prepare your .NET libraries to get also used on Linux and Mac. That's pretty awesome. Have you really thought about that a few years ago? ;)

A pretty detailed tutorial about how to move libraries to DNX was written by Marc Gravell: http://blog.marcgravell.com/2015/11/the-road-to-dnx-part-1.html

AppVeyor: A simple build server for open source projects

18.11.2015 17:00:00 | Jürgen Gutsch

For LightCore 2.0 I would like to show the build state inside the GitHub repository. I could use my personal Jenkins build server on a Azure VM, because Jenkins also provides the build state, with a plug-in.

But this seems to be the right moment to play around with AppVeyor:

https://ci.appveyor.com/project/JuergenGutsch/lightcore

AppVeyor is a browser based SaaS (Software as a Service) application in the cloud. AppVeyor provides many useful features within a pretty simple, intuitive and clean UI. GitHub is completely integrated and it is really easy to create a build job for a GitHub project:

The .NET Version Manager (DNVM) is already installed and you only need to figure out which run-time is used by default. I used the build output to see the results of the "dnvm" commands. Finally I choosed the way to install the needed beta-8 with the batch scripts, every time the build starts:

dnvm update-self
dnvm install 1.0.0-beta8 -a x86 -r coreclr -OS win 
dnvm alias lccoreclr 1.0.0-beta8 -a x86 -r coreclr -OS win 
dnvm install 1.0.0-beta8 -a x86 -r clr -OS win
dnvm alias lcclr 1.0.0-beta8 -a x86 -r clr -OS win

For the builds and the tests I also used the batch command mode with the following lines:

Build:

cd LightCore 
dnvm use lccoreclr 
dnu restore 
dnu build

Test:

cd ..\LightCore.Tests 
dnvm use lccoreclr 
dnu restore 
dnx test 

Show the build state

Finally I'm able to copy a small piece of MarkDown code, which I can use in the readme.md file in the GitHub repository to show the current build state:

[![Build status](https://ci.appveyor.com/api/projects/status/et1fpjlmnsrkw3mv?svg=true)](https://ci.appveyor.com/project/JuergenGutsch/lightcore)

Build Status

As you can see, it is pretty simple to use and handle AppVeyor. I'm sure I'll also use AppVeyor for my other open source project, the "SimpleObjectStore". But I need to move that library to .NET Core first. ;)

ASP.Net 5: In welchem NuGet-Paket ist der gewünschte Typ?

17.11.2015 06:30:50 | Johnny Graber

Mit ASP.Net 5 (ehemals vNext) kommen etliche Neuerungen auf einem zu. Eine der grössten dürfte das dynamisch zusammenstellbare .Net Core sein. Statt wie bisher das ganze .Net Framework zu verwenden, kann man nun nur noch das nutzen, was man wirklich benötigt. Diese Flexibilität bringt nicht nur Vorteile, sondern auch neue Herausforderungen: In welchem der unzähligen … ASP.Net 5: In welchem NuGet-Paket ist der gewünschte Typ? weiterlesen

AppVeyor: Einfacher und intuitiver Build-Server für Open Source Projekte

17.11.2015 00:15:00 | Jürgen Gutsch

Für LightCore 2.0 möchte ich öffentlich den Build-Status des Projektes im Repository anzeigen. Ich hätte dafür auch meine Jenkins-Installation auf Azure nutzen können, denn auch Jenkins zeigt über ein Plugin den aktuellen Build-Status in form einer kleinen Grafik an.

Allerdings war das jetzt mal der richtige Anlass um AppVeyor zu testen:

https://ci.appveyor.com/project/JuergenGutsch/lightcore

AppVeyor steht als SaaS (Software as a Service) über eine Web-UI zur Verfügung und bietet relativ viel Möglichkeiten über eine recht einfache, intuitive und aufgeräumte Oberfläche. Sehr leicht kann hier das GitHub Projekt eingebunden werden:

image

Eine kleine Herausforderung war hier eigentlich nur der Build eines .NET Core Projektes und die Ausführung der XUnit Tests innerhalb eines .NET Core Projektes. Aber auch das war schnell eingerichtet, da der .NET Version Manager (DNVM) bereits installiert ist. Man musste nun lediglich herausfinden welche DNX Version installiert ist, bzw. die richtige nachinstallieren. So nutzte ich die ersten paar Builds um über den Build-Output die vorhandenen Runtimes zu ermitteln. Am Ende lasse ich aber dann doch einfach gewünschte beta-8 installieren:

image

dnvm update-self
dnvm install 1.0.0-beta8 -a x86 -r coreclr -OS win 
dnvm alias lccoreclr 1.0.0-beta8 -a x86 -r coreclr -OS win 
dnvm install 1.0.0-beta8 -a x86 -r clr -OS win
dnvm alias lcclr 1.0.0-beta8 -a x86 -r clr -OS win

Bei Build und Test muss ich jeweils die Kommandozeile wählen und folgende Zeilen einfügen:

Build:

image

cd LightCore
dnvm use lccoreclr
dnu restore
dnu build

Test:

image

cd ..\LightCore.Tests
dnvm use lccoreclr
dnu restore
dnx test

Anzeige

Am Ende kann ich mir auf AppVeyor ein Stück MarkUp Code kopieren, dass ich in die Readme.md Datei im Repository einfügen kann, um den aktuellen Buid-Status des Projektes anzuzeigen:

image

[![Build status](https://ci.appveyor.com/api/projects/status/et1fpjlmnsrkw3mv?svg=true)](https://ci.appveyor.com/project/JuergenGutsch/lightcore)

Wie man sieht ist AppVeyor relativ einfach zu handhaben. Ich denke ich werde den SimpleObjectStore ebenfalls hierüber bauen lassen. Vorerst muss ich aber auch dieses Projekt erst nach .NET Core portieren. ;)

LightCore 2.0

16.11.2015 17:00:00 | Jürgen Gutsch

At the MVP Summit 2015 we had a Hackthon with the guys from the ASP.NET product group to support ASP.NET 5. There were Ideas to improve the documentation, to upgrade samples to the newest beta version or to upgrade older libraries to .NET Core.

It was Albert Weinert who asked me to move LightCore to .NET Core. The more I thought about this idea, the more I liked it. So I decided to move LightCore to .Net Core :)

To change the main library wasn't a big deal. I simply created a new DNX library and added the existing code files to the new libraries. I had to solve only three small issues, which is explained a little later.

The biggest effort was to change all the unit tests from NUnit to Xunit, because NUnit was unfortunately not compatible to .NET Core. While changing the test framework I also changed the assertions to FluentAssertion to be save in the future, if we need to change the the test framework again.

Now, with the version 3.0.0 NUnit supports .NET Core (Universal Windows Apps 10+, DNX Core 5+) https://www.nuget.org/packages/NUnit/

Current status

In the new version I did a hard cut with Silverlight and the Compact Framework. I don't want to support this old frameworks. If the .NET core libraries are compatible with that two frameworks, this will only be by accident ;)

This version will support .NET Core 5, UWP10, .NET Framework and Mono. ASP.NET 4.6 and ASP.NET 5 is also supported.

The XAML-Reader is not available in .NET Core, which means the XAML configuration will only work in with .NET Framework. In .NET Core a JSON configuration should be used instead, which is additionally available for all other Frameworks. The configuration by code is still possible and is the recommended way to configure the IoC container.

The old web integration will not be changed, to stay compatible to MVC 3 and 4. This library only uses the new .NET Framework version of the LightCore main library. Additionally we will add a ASP.NET 5 integration to replace the build in IoC with LightCore.

The ThreadSingeltonLifecycle is currently not working in the .NET Core version, because System.Threading.Thread is not available in .NET Core. We need to find another solution to identify the current thread. This live-cycle only works in .NET Framework.

In case of reflection to get the properties to inject, the BindingFlags.SetProperty is not available in .NET Core. This means there are possibly some performance issues, while fetching and validating the property setter.

Another issue is the CommonServiceLocator, because the ServiceLocatorImplBase of the Microsoft.Practices.ServiceLocation is also not yet available in .NET Core. So the CommonServiceLocator is only working with .NET Framework. Maybe it is needed to build an own ServiceLocator.

With the unit tests of LightCore.Configuration we had problems with three tests which were failing, if they are not running individually. This is because the Xunit tests where run in parallel and the RegistrationLoader in LightCore is not ThreadSave. This guy mus not be thread save, but we needed to wrap all tests with an lock statement which are using RegistrationLoader.Instance.Register() to solve that problem.

A public build server is set up with AppVeyor, but we also need to integrate the other libraries into this build.

More ideas

  • Property injection should only work with an marker attribute to improve the performance
  • Some users want to have the named instances back in LightCore. I believe we should add this feature again. It is definitely not a nice pattern to use named instances, but as always in the real world we can't use all the nice patterns every time

Call for contributions

As already written, we need to change the web integrations and the samples, documentations and the performance tests, though. You are able to follow the current development process on the related feature branch: https://github.com/juergengutsch/lightcore/tree/jg/portable

It would be pretty cool, if you would contribute some ideas, suggestions and issues directly on GitHub. Please also feel free to send us code contributions via pull requests :)

We would like to make LightCore one of the best IoC containers for .NET Core :)

LightCore 2.0

16.11.2015 00:56:00 | Jürgen Gutsch

Beim MVP Summit gab es am letzten Tag ein Hackathon mit dem Ziel ASP.NET 5 zu unterstützen. Das Hauptanliegen war sicher die Dokumentation, aber es ging auch darum Samples und Bibliotheken auf die neuesten Version von ASP.NET 5 und .NET Core zu heben.

Albert Weinert war es, der mich auf die Idee brachte LightCore auf .NET Core zu heben. Also habe ich ich den Tag drangesetzt die Bibliothek .NET Core kompatibel zu machen. Der größte Aufwand lag nicht darin, die eigentliche Bibliothek für .NET Core zu bauen, sondern alle Unit-Tests von NUnit nach XUnit zu portieren. Im gleichen Zuge habe ich die NUnit Asserts durch FluentAssertion ersetzt. Ein zukünftiger Wechsel des Test-Frameworks sollte dann kein Problem so großes Problem mehr sein.

Aktueller Stand

In der neuen Version habe ich in Bezug auf Silverlight und Compact Framework einen harten Schnitt gemacht. Diese Plattformen werden nicht mehr direkt unterstützt. Sollte die .NET Core Bibliothek kompatibel zu Silverlight und Compact Framework sein (was ich im Moment weder ausschließen noch bestätigen kann) so ist das eher Zufall.

Unterstützt werden ASP.NET 5, UWP, .NET Framework und Mono.

Abstriche muss LightCore in der LightCore.Configuration unter .NET Core machen, da der XAML-Reader nicht zur Verfügung steht. Diesen werde ich nur für das .NET Framework aktivieren. In allen anderen Fällen wird es eine JSON Konfiguration geben. Die JSON Konfiguration soll die bevorzugte Art der Konfiguration für ASP.NET 5 und UWP sein, abgesehen von der Konfiguration per Code natürlich.. 

Die alte Integration Web wird nicht angefasst, um Kompatibel zu MVC3 und -4 zu bleiben, verweist aber auf die .NET Core Version von LightCore. Zusätzlich wird es aber eine ASP.NET 5 Integration geben.

Der ThreadSingeltonLifecycle Manager ist aktuell für .NET Core deaktiviert, da System.Threading.Thread nicht mehr zur Verfügung steht. Hier muss eine andere Lösung gefunden werden, um die aktuellen Threads zu identifizieren. Dieser Livecycle wird vorläufig nur unter .NET Framework zur Verfügung stehen.

Im Falle von Reflection beim ermitteln von zu injizierenden Eigenschaften steht unter NET Core der BindingFlags.SetProperty nicht zur Verfügung, es werden hier also Performance-Einbußen möglich sein, wenn nun Eigenschaften ohne Setter ermittelt und geprüft werden müssen.

Eine weitere Baustelle ist der CommonServiceLocator, da die ServiceLocatorImplBase unter Microsoft.Practices.ServiceLocation noch nicht für .NET Core zur Verfügung steht. Eventuell macht eine eigene Implementation für .NET Core mehr Sinn. Der CommonServiceLocator bleibt für das .NET Framework bestehen.

Bei den Unit-Tests zur LightCore.Configuration gab es Probleme mit drei Tests die fehlschlagen, wenn sie nicht einzeln aufgerufen werden. Das liegt daran, dass XUnit die Tests parallel ausführt und der RegistrationLoader in LightCore nicht Thread-Save ist und auch nicht zwingend sein muss. Die verhauen sich also gegenseitig die Referenzen. Ein Lock um alle Tests die RegistrationLoader.Instance.Register() aufrufen behebt das Problem.

Ein öffentlicher Buildserver – mit AppVeyor - ist ebenfalls eingerichtet

Weitere Ideen

  • Die Idee Property-Injection ausschließlich über ein MarkerAttribut zuzulassen steht wieder im Raum. Das würde die Performance an dieser Stelle erhöhen.
  • Der Wegfall von benannten Instanzen wurde mehrfach kritisiert. Ich kann mir vorstellen, dass dieses Feature wieder Einzug findet. Natürlich ist das kein optimales Pattern, aber wie in allen Fällen, können schöne Patterns in der realen Welt nicht immer durchgezogen werden.

Contributions needed

Wie bereits geschrieben, müssen die Web Integrationen noch umgestellt werden, sowie alle Samples, Dokumentationen und die Performance-Tests.

Den aktuellen Stand könnt ihr auf GitHub direkt in folgendem Feature-Branch mitverfolgen: https://github.com/juergengutsch/lightcore/tree/jg/portable

Ich würde euch bitten Ideen, Anregungen und Probleme ebenfalls auf GitHub einzutragen.

Wer sich aktiv an der Entwicklung beteiligen möchte, ist herzlich eingeladen. Forkt auch den Stand, holt auch den Feature-Branch und schickt mir die Pull-Requests.

My First Post with Pretzel

14.11.2015 17:00:00 | Jürgen Gutsch

Bye Community Server, Hello Pretzel

I stop writing on http://www.aspnetzone.de/blogs/juergengutsch/ and changed the blog software to a more flexible and agile system based on Pretzel. Pretzel is a Jekyll clone written in .NET using a funny API. You need to 'taste' your blog to view your latest changes in your browser locally and you need to 'bake' your Pretzel blog before delivering your changes to the server.

Markdown instead of Markup

Like Jekyll, you need to use Markdown to write your blog posts for Pretzel. So, I also changed the offline editor to MarkdownPad 2. Markdown helps me to focus on content, instead of formatting. E. g. with the old blog system I had to format the code blocks online in the system after publishing, because the Windows Live Writer didn't support the code formats of the system in the right way.

In general, writing offline is one of the most important requirements I have to a blog system. Because I travel a lot with the train and the "Deutsche Bahn" (the German railway company) seems to be pretty incompatible with the internet ;)

Switching to English

I also switched to English, because I used to speak and to write English almost every day. And this is also a way to get more experience in writing and speaking English. Please feel free to send me notes and hints about spelling errors :)

Hopefully this is also fine for the most of the German speaking readers of my blog. Currently I have around 1000 activities per day via the FeedBurner feed and around 400 views per day directly on the articles. If you are not happy about the English posts, please drop me a note. Maybe it is possible to share the contents also in German.

From time to time I will translate the most important blog posts of the old system, to use it in the new system. I will select the specific posts by the number of reads.

This blog ...

... is still is not completely configured and there are some features I need to implement. Especially the Tags are currently disabled, because I need to hack around Pretzel a little bit to create tag overviews. Maybe I will arrange some things around the layout, colors and so on...

A very huge "Thank You" ...

... goes to Marian Gieseler, a colleague of mine at the YooApplications AG who creates the initial design of this blog. I'm pretty happy with this layout and proud to present it to the world :)

Windows 10 in der Praxis

13.11.2015 00:39:00 | Jürgen Gutsch

Sodele… Nun sind es über 2 Monate, dass ich Windows 10 auf einem neuen Dell XPS 13 nutze.

Gegen die Hardware kann ich absolut nichts sagen. Das Gerät ist Top und vor allem klein und leicht, was es zu einem perfekten Arbeitsgerät macht, wenn man viel im Zug unterwegs ist wie ich.

Auch das Windows 10 ist im großen und ganzen in Ordnung, einzig ein Luxusproblem ist relativ störend – nachdem ich mich an das unnötige Startmenü gewöhnt habe, dass ich eigentlich seit WinXP nicht mehr benutzt habe. Bei dem Luxusproblem handelt es sich darum, dass Windows 10 mit der hohen Auflösung des XPS 13 nicht 100% klarkommt (Anwendersicht)

Das Gerät hat eine Auflösung von 3200 x 1800 Pixeln, was im Alltag bei dem kleinen Bildschirm keinen Sinn macht. Daher skaliert Win10 auch – fast - alles um 225%. Das ist im Prinzip auch eine sehr gute Idee, wäre es nicht “fast” alles, was skaliert wird.

Ausgerechnet das SQL Server “Management Studio” und der “Windows Live Writer” skalieren nur Teilweise. Diverse Icons und Dialoge bleiben klein. Auch Checkboxen und Radiobuttons werden nicht skaliert. Text dagegen schon. Im Live Writer wird die Breite des Arbeitsbereiches nicht skaliert, aber der Text, so das man eigentlich keinen Platz mehr zum schreiben hat.

Auch andersrum gibt es Probleme, also wenn die Skalierung auf den Hauptschirm stimmt, aber beim verschieben auf einen weiteren Bildschirm mit geringerer Auflösung die Applikation nicht mehr herunterskaliert wird. Das passiert z. B. bei “Skype for Business” oder bei PowerPoint. Bei letzterem sind es vor allem die Ribbons die dann fast ein viertel des Bildschirms ausmachen.

Ich könnte darüber nachdenken, externe Bildschirme mit höherer Auflösung anzuschaffen, allerdings wird immer alles in doppelter Ausführung benötigt, damit ich im Geschäft und im Home-Office gleich gut arbeiten kann. Einfacher war es allerdings Win10 generell mit einer geringeren Auflösung zu fahren. So habe ich die Skalierungsprobleme sowohl auf den Gerätebildschirm als auch mit externen Bildschirmen behoben.

Wahrscheinlich wäre es bessern, wenn Windows 10 die Skalierung übernimmt, statt es der laufenden Software zu überlassen. Eine Lösung könnte sein, der Software eine geringere Auflösung vorzumachen und dann das Bild zu skalieren. Sicher nicht ganz einfach, aber dann würde es die Probleme nicht geben.

Alles andere funktioniert problemlos. Visual Studio, Outlook, Word, etc. machen absolut keine Probleme.

So finden Sie 5 Memory Leaks, die auch in Ihrer .NET Anwendung sein könnten.

10.11.2015 09:41:34 | Andre Kraemer

Auf die Frage “Hätten Sie gerne noch ein paar Memory-Leaks in Ihrer Anwendung?” würden die meisten Kunden vermutlich vehement mit “Nein” antworten. Und das selbst wenn die Leaks kostenfrei wären. Obwohl die wenigsten Anwender also Memory Leaks wünschen, liefern Entwickler sie trotzdem regelmäßig mit ihren Anwendungen aus. Selbstverständlich geschieht dies nicht bewusst. Stattdessen schleicht sich das Leak still und heimlich in die Applikation und entfaltet seine volle Wirkung erst im Produktivbetrieb beim Kunden.

Als .NET Anwendungsentwickler sind wir uns natürlich keiner Schuld bewusst, schließlich gibt es unter .NET dank des Garbage Collectors gar keine Memory Leaks mehr. Zumindest in der Theorie! In der Praxis befinden sich jedoch in relativ vielen Anwendungen Memory Leak  ähnliche Zustände, die zum unkontrollierten Anwuchs des Speicherverbrauchs einer Anwendung führen und im schlimmsten Fall mit einem Absturz enden.

In meinen ersten Jahren auf der .NET Plattform bin ich selbst oft genug in die Memory Leak Falle hereingetappt. Nach anfänglicher Ratlosigkeit arbeitete ich mich mühevoll in windbg ein und rückte so den Memory Leaks auf die Pelle. Mittlerweile habe ich zwar das Werkzeug gewechselt und nutze statt windbg meist den Redgate Ants Memory Profiler, trotzdem analysiere ich weiterhin regelmäßig Memory Leaks unter .NET. Nicht nur meine eigenen, sondern auch die meiner Kunden. Eine Auswahl der fünf häufigsten bzw. gemeinsten Leaks habe ich Ende 2014 in einem Vortrag zusammengefasst, den ich seitdem auf mehreren Konferenzen und User Group Treffen gehalten habe. Als ich den Vortrag vorbereitet habe ging ich davon aus, dass es sich um ein “Randgruppenthema” handelt, dass nur relativ wenige Teilnehmer interessieren wird. Tatsächlich war jedoch das Gegenteil der Fall. Der Memory Leak Vortrag war mein bisher erfolgreichster. Auf jeder Konferenz war der Vortrag so gut besucht, dass zum Teil einige Teilnehmer sogar auf dem Boden sitzen oder stehen mussten.

Eines der persönliches Highlights für mich war es den Vortrag während der C# Days der BASTA Spring 2015 und auch auf der Herbst-BASTA 2015 halten zu dürfen. Die Aufzeichnung des BASTA Spring Vortrags ist mittlerweile online. Der Einfachheit halber habe ich das Video direkt hier im Blog eingebunden.

In dem Video erkläre ich folgendes:

  • Wie funktioniert der .NET Garbage Collector
  • Wie geht man bei der Analyse von Memory Leaks systematisch vor
  • Welche Leaks befinden sich typischerweise in .NET Anwendungen
  • Wie behebt man gefundene Leaks schnell und zuverlässig

Wer also gerne lernen möchte, wie er Memory Leaks in der eigenen Anwendung finden kann, der sollte sich auf jeden Fall einmal das Video ansehen. Der Quellcode des Vortrags befindet sich übrigens online auf github. Somit kann jeder der möchte gerne selbst auf die Suche gehen. Außerdem unterstütze ich auch sehr gerne bei der Memory Leak Analyse des eigenen Quellcodes.

Über Kommentare, entweder hier im Blog, oder direkt auf Youtube freue ich mich natürlich.

So finden Sie 5 Memory Leaks, die auch in Ihrer .NET Anwendung sein könnten.

10.11.2015 09:41:34 | Andre Kraemer

Auf die Frage “Hätten Sie gerne noch ein paar Memory-Leaks in Ihrer Anwendung?” würden die meisten Kunden vermutlich vehement mit “Nein” antworten. Und das selbst wenn die Leaks kostenfrei wären. Obwohl die wenigsten Anwender also Memory Leaks wünschen, liefern Entwickler sie trotzdem regelmäßig mit ihren Anwendungen aus. Selbstverständlich geschieht dies nicht bewusst. Stattdessen schleicht sich das Leak still und heimlich in die Applikation und entfaltet seine volle Wirkung erst im Produktivbetrieb beim Kunden.

Als .NET Anwendungsentwickler sind wir uns natürlich keiner Schuld bewusst, schließlich gibt es unter .NET dank des Garbage Collectors gar keine Memory Leaks mehr. Zumindest in der Theorie! In der Praxis befinden sich jedoch in relativ vielen Anwendungen Memory Leak  ähnliche Zustände, die zum unkontrollierten Anwuchs des Speicherverbrauchs einer Anwendung führen und im schlimmsten Fall mit einem Absturz enden.

In meinen ersten Jahren auf der .NET Plattform bin ich selbst oft genug in die Memory Leak Falle hereingetappt. Nach anfänglicher Ratlosigkeit arbeitete ich mich mühevoll in windbg ein und rückte so den Memory Leaks auf die Pelle. Mittlerweile habe ich zwar das Werkzeug gewechselt und nutze statt windbg meist den Redgate Ants Memory Profiler, trotzdem analysiere ich weiterhin regelmäßig Memory Leaks unter .NET. Nicht nur meine eigenen, sondern auch die meiner Kunden. Eine Auswahl der fünf häufigsten bzw. gemeinsten Leaks habe ich Ende 2014 in einem Vortrag zusammengefasst, den ich seitdem auf mehreren Konferenzen und User Group Treffen gehalten habe. Als ich den Vortrag vorbereitet habe ging ich davon aus, dass es sich um ein “Randgruppenthema” handelt, dass nur relativ wenige Teilnehmer interessieren wird. Tatsächlich war jedoch das Gegenteil der Fall. Der Memory Leak Vortrag war mein bisher erfolgreichster. Auf jeder Konferenz war der Vortrag so gut besucht, dass zum Teil einige Teilnehmer sogar auf dem Boden sitzen oder stehen mussten.

Eines der persönliches Highlights für mich war es den Vortrag während der C# Days der BASTA Spring 2015 und auch auf der Herbst-BASTA 2015 halten zu dürfen. Die Aufzeichnung des BASTA Spring Vortrags ist mittlerweile online. Der Einfachheit halber habe ich das Video direkt hier im Blog eingebunden.

In dem Video erkläre ich folgendes:

  • Wie funktioniert der .NET Garbage Collector Wie geht man bei der Analyse von Memory Leaks systematisch vor Welche Leaks befinden sich typischerweise in .NET Anwendungen Wie behebt man gefundene Leaks schnell und zuverlässig

Wer also gerne lernen möchte, wie er Memory Leaks in der eigenen Anwendung finden kann, der sollte sich auf jeden Fall einmal das Video ansehen. Der Quellcode des Vortrags befindet sich übrigens online auf *github. Somit kann jeder der möchte gerne selbst auf die Suche gehen. Außerdem unterstütze ich auch sehr gerne bei der Memory Leak Analyse des eigenen Quellcodes.

Über Kommentare, entweder hier im Blog, oder direkt auf Youtube freue ich mich natürlich.

Einfacher Dateienzugriff mit ASP.NET 5 Hosting Environment

02.11.2015 17:03:00 | Jürgen Gutsch

Wer auf Dateien zugreifen möchte, sollte sich einfach nur das IHostingEnvironment in seinen Service holen. 

private readonly IHostingEnvironment _env;

public AuthMessageSender(IHostingEnvironment env)
{
    _env = env;
}

_env.WebRootFileProvider ermöglicht den schnellen Zugriff auf Dateien im Ordner wwwroot,  bzw. in dem Ordner der in der project.json beim “webroot” hinterlegt ist. Dieser FileProvider wiederum kann mit GetFileInfo() einer angegebenen IFileInfo liefern, die relativ im Ordner wwwroot gesucht wird. Die Methode GetDirectoryContents() ermöglicht einem den schnellen Zugriff per LINQ auf Inhalte eines Verzeichnisses. Mit der Methode Whatch() lassen sich Dateien beobachten, dabei lassen sich die zu beobachtenden Dateienüber einen Filter spezifizieren.

Das genannte IFileInfo ist eine reduzierte Version des bekannten System.IO.FileInfo, aber auch das bietet eine kleine Unterstützung: Die Methode CreateReadStream() öffnet direkt einen Strem der Datei im Lesemodus.

var document = new Document(name);

var fi = _env.WebRootFileProvider.GetFileInfo($"App_Data/{name}.md");
if (!fi.Exists)
{
    throw  new FileNotFoundException("Resource not found '{0}'!", $"App_Data/{name}.md");
}

var fs = fi.CreateReadStream();

await fs.CopyToAsync(document.Stream);

document.LastModified = fi.LastModified.DateTime;

return document;

Um relative Pfade in absolute Pfade zu mappen, kommt eine altbekannte Methode zum Einsatz, die hier als Erweiterungsmethode auf den IHostingEnvironment angelegt ist. Dabei handelt es sich um die MapPath Methode, die einigen noch aus dem Server Objekt im HttpContext.bekannt sein dürfte.

var absolutPath = _env.MapPath(“App_Data/content.md”);

Regeln | Impressum