📜 ⬆️ ⬇️

Preparing an ASP.NET Core: Creating Your Cross-Platform Modular Framework

We continue our column on the topic ASP.NET Core by another publication from Dmitry Sikorsky ( DmitrySikorsky ) - the head of the company “Yubreinians” from Ukraine. This time, Dmitry talks about his experience in developing a modular cross-platform framework based on ASP.NET Core. Previous articles from the column can always be read on the link #aspnetcolumn - Vladimir Yunev
Due to the specifics of my task, lately, quite a lot has to reflect on the modular and extensible architecture of web applications on ASP.NET Core (and before that - on ASP.NET of the previous version). As a result, ExtCore appeared - a small open-source cross-platform framework that allows you to literally simply connect a NuGet-package to turn your web application into a modular and extensible.


Main features


ExtCore can detect and use types (as well as views and static content) defined both in projects (as source code or NuGet packages), which are explicitly referenced, and in projects that are located in a specific folder in compiled dll assemblies.

For convenience, optionally, these projects can be conditionally combined into extensions (i.e., each extension can consist of one or many projects). Also, each extension can have a class (in one of the projects) that implements the IExtension interface, and ExtCore, in turn, allows at any time to get an accessible set of instances of all classes that implement this interface. You can use these classes to provide metadata describing extensions, initializing extensions (for example, registering routes), and so on.
')
Although the framework itself does not contain any functionality related to working with data, all that is necessary for this (including the common storage context for all extensions) is implemented in the ExtCore.Data extension, which is described below.

aspnetcolumngithub Tip! You can try everything yourself or by downloading the source code from GitHub https://github.com/ExtCore/ExtCore-Sample .

How it works


During application startup, ExtCore detects all assemblies (those that are explicitly referenced, and those that are not explicitly referenced, but which are located in a specific folder). Only assemblies that contain a link to ExtCore.Infrastructure are selected and loaded.

Further, all detected assemblies that meet the selection criteria are placed in the container container ExtensionManager, from where they can be obtained from anywhere at any time (that is, from the main application project or from any other project). These assemblies are “registered” as sources for searching for controllers (all controllers from assemblies that are explicitly referenced are detected by ASP.NET automatically, but the rest must be reported additionally, “manually”), views (and in the form of resources, and compiled) and static content.

After that, a number of IExtension methods are executed among instances of the available implementations of this interface. So extensions can run their code during the execution of ConfigureServices, Configure, and so on.

Recommended Expansion Structure


To simplify understanding and preserve uniformity, it is convenient to adhere to the following structure when developing your own extensions (where X is the name of your extension):


YourApplication. X

The main expansion project. Contains a class that implements the IExtension interface, as well as general classes used in other projects. If the extension does not contain different areas (for example, frontend and backend), then things related to the user interface (controllers, view models, views, etc.) can also be placed in this project.

YourApplication.X.Frontend and YourApplication.X.Backend

The projects are named for example only. It seems to me convenient to separate different parts of the user interface in this way (especially during team work). Also, if a web application consists of a large number of extensions, you can take common elements of the frontend and backend into basic projects and then refer to them in all the others. Thus, for example, all extensions can have a uniform appearance or a set of basic controls with the ability to simply replace it by copying one or another DLL file.

ExtCore supports two options for working with views (at the same time): representations in the form of resources and precompiled representations. In short, I recommend using the second option. You can read more about methods of working with views applied in ExtCore in the article Preparing ASP.NET Core: let's talk about non-standard approaches when working with views .

Working with static content is also easy. In the article Preparing ASP.NET Core: how to present static content as resources describes the method used in ExtCore. To summarize the article, the necessary static content is placed into assemblies as resources and then these assemblies are “registered” as file providers, which makes it possible to use resources almost like ordinary physical files (including direct access via HTTP ).

Interestingly, the scope of both views and static content is the entire application. This means that some extensions can use the contents of other extensions and vice versa. Moreover, extensions can use views and static content from the main web application. In this way, you can, for example, describe the logic in extension projects, but allow the user to determine how everything will look, right in the main application.

YourApplication. X. Data. *

Projects that describe working with data. More on this below.

Work with data

ExtCore additionally has an optional ExtCore.Data extension that implements all the necessary basic functionality for working with data. The central element of the extension is the interface IStorage (unit of work). This interface describes only 2 methods: GetRepository and Save. The GetRepository implementation detects and returns an accessible instance of the repository that implements the requested interface (as well as the IRepository) and ensures that all repositories have a single storage context (IStorageContext interface).

If you need some kind of registration of entity types from different extensions (as in the case of EntityFramework, for example), this can be easily achieved using something like the IModelRegistrar interface, which is used in ExtCore.Data.EntityFramework.Sqlite and ExtCore.Data .EntityFramework.SqlServer. A test project (link to it at the end of the article) illustrates this approach.

The expansion structure is as follows:


ExtCore.Data

The project contains a class that implements the IExtension interface. When the application is started, this class executes code that detects an available implementation of the IStorage interface (see below) and registers it in the ASP.NET Core DI embedded so that any controller can then get an instance of it if necessary. Conveniently, you can change the type of supported storage by simply changing the link in the dependencies or copying the DLL file.

ExtCore. Data. Models. Abstractions

The project describes the IEntity interface, which all entities in all extensions must implement.

ExtCore. Data. Abstractions

The project describes the key interfaces IStorageContext, IStorage and IRepository, which I described above. In my own extensions, in projects with names like YourApplication.X.Data.Abstractions, I put repository interfaces to then work through them without reference to the implementation of a specific repository.

ExtCore. Data. EntityFramework. Sqlite and ExtCore. Data. EntityFramework. SqlServer

The project contains classes that implement interfaces from ExtCore.Data.Abstractions for specific storages (in this case, Sqlite and SqlServer).

findings


At the moment - this is only the alpha version. I have many plans for the development of the project (connecting and disconnecting extensions at any time and general optimization; I also want to work on the ExtensionManager class, add a convenient opportunity to get available implementations of specified interfaces, and not just IExtension). I use this framework in my project (CMS). As far as I can tell, it’s convenient and flexible. I will be glad to hear comments and criticism. Thank!

Here is the link to the source: https://github.com/ExtCore/ExtCore .

And here is the link to the finished test project: https://github.com/ExtCore/ExtCore-Sample .

To authors


Friends, if you are interested in supporting the column with your own material, please write to me at vyunev@microsoft.com to discuss all the details. We are looking for authors who can interestingly tell about ASP.NET and other topics.

about the author


Sikorsky Dmitry Alexandrovich
Jubreynians Company ( http://ubrainians.com/ )
Owner, Head
DmitrySikorsky

Announcement! Deep Intense at the DevCon 2016 Conference


image

We are pleased to announce the holding of a deep intensive course on ASP.NET Core at the [DevCon 2016 conference] (https://events.techdays.ru/DevCon/2016/registration). This course will take place on the second day of the conference and will take a full day of the conference for 6 hours.

Development of modern web applications on the open platform ASP.NET 5
As part of this intense, participants will take part in an exciting and adventurous journey dedicated to developing web applications on the latest ASP.NET platform 5. We will go all the way from zero to a full-fledged application deployed in the cloud. And on the way, participants will be able to stop to explore the internal structure of ASP.NET, work with relational and NoSQL databases using the Entity Framework 7, develop applications on the MVC framework, build models, views and business logic, create a REST API, and organize continuous development processes. and testing using Git and Visual Studio Online, as well as deploying using Azure and Docker containers. At the end of the trip, all participants will pass the dedication and become deserved knights of ASP.NET.

Registration for the DevCon 2016 conference is already open! Sign up here .

Source: https://habr.com/ru/post/278247/


All Articles