change appdomain of a nuget project - c#

I am running ASP.NET MVC web application, with a nuget project merged inside of it. So basically I have got two projects inside of one. The nuget project is being initialized when ASP.NET MVC starts up.
ASP.NET MVC runs in DefaultDomain appdomain, while nuget project runs in something like that - /LM/W3SVC/1/ROOT-(...), so I assume that it runs as a root. Now, I don't want it to be run as a root, anything but a root would be good. How can I change it?

You can't change AppDomain where each individual sites are running. The name is set by ASP.Net runtime (there is one default AppDomain and one AppDomain per site).
Depending on your actual problem - either create new app domain or be happy with default ASP.Net setup.
Note that: projects don't "run in an app domain", in most cases resulting exe/dll is loaded into an AppDomain... There is no direct correlation between projects and AppDomains.

Related

Consequences of changing a .Net 5 project Sdk

Context
I'm working on a 'plugin-like' system that runs as a windows service. The windows service creates a generic IHost (Let's call this the root Host) which I want to create as web server. The root Host will then look for plugin dll's to load, and it'll create individual IHost's for each plugin (call these child hosts).
Each of these child hosts can run their own kestrel server. I have it set up so that the root host server will act as a reverse proxy to these child host servers. This way only the root host server has to be exposed publicly.
I want to make it so both the root and child host servers can have Api Controllers and serve MVC razor pages.
My Question
It seems that razor pages cannot be used unless the project Sdk is either Microsoft.NET.Sdk.Web or Microsoft.NET.Sdk.Razor. It also seems like the Windows service project (One that starts the root host) has to specifically be Microsoft.NET.Sdk.Web or it wont add the needed application parts.
At the same time though, Microsoft says to use the Microsoft.NET.Sdk.Worker for Worker Service Template's. So I'm wondering what the consequences of using the Microsoft.NET.Sdk.Web sdk for a windows service project are? I assume it causes different MSBuild tasks to be setup, plus different DLL's to be loaded in, but is this stuff that can be done in other ways?
If it's not a good idea to use Microsoft.NET.Sdk.Web, would it be a smarter idea to move all the root host web server stuff to its own project? The windows service project would then just get the IHost from this project and then could go back to being a Microsoft.NET.Sdk.Worker project?
Edit
I ended up going with a restructure of my projects. It's now split up into 3 distinct projects instead of the 2 I originally had.
Core Project
The core project is just a standard Microsoft.NET.Sdk. It has an extension method for IHostBuilder called ConfigureHostRoot which adds the IHostedService's needed to look for and load the 'plugins'.
Http Project
This project is of the type Microsoft.NET.Sdk.Web. It has an extension method for IHostBuilder called ConfigureWebHostProxy which will add the proxy server. Because this project is the web sdk, it will allow for razor pages to be added.
Windows Service Project
I needed a third project to bring those 2 separate parts together. This is the job of the Windows Service. This project is of the type Microsoft.NET.Sdk.Worker, and is the only entry point for the entire system.
All it has is the standard Program.cs with a Main(). All the main does it builds the Host like this:
Host.CreateDefaultBuilder(args)
.ConfigureHostRoot(integrationBuilder =>
{
// Configure the Host root
})
.ConfigureWebHostProxy(proxyBuilder =>
{
// Configure the reverse proxy
});
Then it'll just build that host and run it for the lifetime of the windows service. Seems like this will work for me, and it means that my core project doesn't have to be a Microsoft.NET.Sdk.Web sdk which I like.
I still don't really know if there is any 'downside' to putting it all into the 'core' project and setting it's sdk to Microsoft.NET.Sdk.Web.

How can I run a code once per application domain in .NET Core

We have a library that is used by multiple companies. They have read-access to built DLL files which are obfusticated.
For each project this library is used, they should pay us. We want to have a telemetry system to make sure that they don't run this library in a non-agreed project.
We thought about somehow calling a telemetry URL each time a process on Windows is started that loads our DLL files. But we need to do it without requiring any coding or configuration from their side.
Is that possible? Can we implement a mechanism in .NET Core inside our library that whenever loaded inside the AppDomain is called once per process lifecycle?
Of course I know we can write code at Program.cs, but in our case, we don't have access to Program.cs and we can't ask them to code, or config anything.

Will two identical dll's be both loaded (if located in different locations and referenced by two different applications)

Suppose I have two ASP.NET web sites hosted on IIS. Both have the same DLL assembly "1.dll" in the bin folder. Will both "1.dll" DLL's be loaded by CLR, or is it smart enough to load it once and afterwise check if assemly with the required version/name was already loaded elsewhere?
Will it make difference if "1.dll" is referenced without requiring specific version?
Will it make difference if both sites are using same or different application pools?
Assemblies are loaded into app domains which is a logical boundary within a process. So if your web application are running in different application pools (I mean different worker process) - Yes, it will load again.
Will it make difference if "1.dll" is referenced without requiring
specific version? No
Will it make difference if both sites are using same or different
application pools? If application pool is same, then it might use shared app domain(though am not very sure)
Update : to answer your second question, i checked loaded assemblies in process explorer for two web sites running in a same pool, different app domains have there own instance of assemblies loaded.

Is it possible to make separate dlls with MVC project?

We have a big project developed in Asp.net MVC5. Our models and business logic are defined in separate class libraries. Now we need to add another module to an existing project but we want a separate dll.
This module also shares the most javascripts, css files and other files. That is the reason we don't want to separate MVC project.
Is there any why we can create separate dll for module basis. so we don't want deploy or touch other dlls.
From your description, you say that the projects share CSS and JS files. This leads me to believe you are talking about a separate MVC website (possibly part of the larger corporate website). This can be easiest with the use of Areas. If you are not familiar with Areas, please read the following: https://msdn.microsoft.com/en-us/library/ee671793(VS.100).aspx
Of course using Areas will require you to deploy the whole site everytime one of the areas change, and you have mentioned that you want to avoid doing so.
If you don't want to use areas, and instead want to create another MVC project in the same solution, you can do that easily too. You can right click on the solution, add new project > ASP.NET web application > MVC to add the project. To share JS and CSS files between these two MVC projects, you will have to create a new solution folder (right click solution > Add new solution folder), and move your resource files to that folder. Inside each MVC project in your solution, you will add existing items and select those js/css resource files. This way if you change the css file, it will be reflected in both the projects.
For more information, read the following:
How do you share scripts among multiple projects in one solution?
Yes you can, just add the logic classes to other class library project (you can have as many as you want), then add references of those class librarys to the mvc project.
Don't forget to import the classes after in your code
Edit: I'm assuming you are using Visual Studio, if yes, you can go to File -> Create Project, this will create another project in the same solution.
I don't know whether you tried with Managed Extensibility Framework (MEF) or not.. this framework works as you required ... I think below link will help you more
ASP.NET MVC Extensibility with MEF
How to integrate MEF with ASP.NET MVC 4 and ASP.NET Web API
http://www.codeproject.com/Articles/167321/MEF-with-ASP-NET-Hello-World
Other people have posted answers regarding the use of Areas. Areas are great and good and helpful. They really benefit the project structure.
This module also shares the most javascripts, css files and other file
The title of your question is about .dlls, but I suspect the client-side resources are the main concern.
If you consider your webapp as having two distinct parts: server-side and client-side, you can use appropriate strategies to modularize each. Areas a great for organizing server-side code, but don't help the front-end.
Front-end package management options have expanded for ASP.NET 5. In addition to the traditional NuGet package manager, Bower and NPM are now supported. For example, consider how this article demonstrates installing jQuery via NPM. Here's another good article about setting up NPM, Bower, and Gulp in Visual Studio.
What to do: Take your existing client-side code and make a custom NPM or Bower package, and then use that package from one or more Asp.NET projects.
I can suggest you two ways to organize your multi-module project.
Option 1 - Create Area per module, within same web project
One way to do it is, create separate Area within the same MVC project. So each module will have a separate area, with separate controllers, views, scripts etc. But,
(1) This will still create a single dll for the whole MVC project
(2) Sharing files across areas might not be very easy in some scenarios (you can keep all the scripts for all the modules in one shared directory though)
Option 2 - Create class library per module, merge after build
Another way is to create a single class library project per module. Add reference to the System.Web.Mvc and other libraries so that it can have controllers etc. Create your own views, scripts and other folders and populate with files as you need them.
Now, all your modules will build as separate projects, with the dll file and the javasvripts, htmls, csss, images etc. To make them all work as a single web application you can create a (only one) MVC web project, which will go to the IIS virtual directory and will be published as web.
To use all your separate modules from the same web, you can write post build events in all those libraries to copy the artifacts (dll, scripts etc.) into the main web, into corresponding folders (dll to \bin, javascript to \scripts etc.). So, after successful build, all the artifacts are available in the same web project, and that can be deployed as a single web with all the modules. Your post build scripts should look something like this
XCOPY "$(ProjectDir)$(OutDir)*.*" "$(ProjectDir)..\YourMainWebDirectory\Bin\" /Y
XCOPY "$(ProjectDir)Content" "$(ProjectDir)..\YourMainWebDirectory\Content\" /S /Y
XCOPY "$(ProjectDir)Scripts" "$(ProjectDir)..\YourMainWebDirectory\Scripts\" /S /Y
XCOPY "$(ProjectDir)Views" "$(ProjectDir)..\YourMainWebDirectory\Views\" /S /Y
XCOPY "$(ProjectDir)Images" "$(ProjectDir)..\YourMainWebDirectory\Images\" /S /Y
Now,
(1) You have separate dlls for separate modules
(2) Can directly share scripts and other files, as they will be in same location (after build)
(3) If you decide to remove a specific module from the web, just remove the post build event from that module (project) without affecting anything else. You can add that back at any time you please.
Your overall solution will look like
Module01.csproj => post build copy to main
\Controllers
\Scripts
\Views
\Contents
\Images
Module02.csproj => post build copy to main
\Controllers
\Scripts
\Views
\Contents
\Images
Models.csproj
\...
Application.csproj
\...
Main.Web.csproj => main web application hosted in IIS
\Controllers
\Scripts
\Views
\Contents
\Images

Is it possible to compile a console application into a single .dll file?

There are 5 console apps working off each other's outputs and are separately installed on my computer (C# 4.0, I am the author) . Management would like to distribute this suite of apps to other users, but aren't thrilled about asking non-tech users to install/configure 5 separate applications. Is there any way I can compile each program down into a .dll and reference them through a single master application?
Q. The main issue seems to be that you don't want 5 separate installation steps?
A. Make an installer for the suite :) Use any MSI builder (WiX, Visual Studio setup projects, InstallShield, and many others; Heck, you could even do an XCOPY deployment in most cases)
Q. How do I directly invoke these programs from within a single process?
A. Options:
Load the assemblies in your AppDomain.
Use a separate AppDomain in case of name(space) conflicts or version conflicts
Q. How do I optionally 'hide' the presence of the external console apps from view
A. Look at ilmerge to possibly combine the 'external' assemblies so they aren't visible anymore. If you can't use ilmerge (conflicts, or e.g. WPF apps) you might embed them as resources and load them on demand as per 1. and 2. above
Update: https://libz.codeplex.com/ is a nice looking project that makes this easy (haven't tried it myself)
Just because each of them is a separate .exe file doesn't mean you can't treat them as one application. And they don't have to be installed or configured separately either.
But a much better solution would be to rewrite each of the applications, so that they expose classes or interfaces that can be used without actually running the application. This way, communication between the parts is going to be much easier.
In .Net, the only difference between .exe and .dll is that you can run .exe directly. But you can treat both as libraries, so you can use functionality from one .exe in another .exe. Another step might be separating the core of each application into a .dll and make the .exes just deal with input and output. With this, the combined application wouldn't have all the code that it doesn't need from the other ones.
Its possible if every assembly is using different class names. Just include the whole source code when you compile the final version in one project.
Go to Project's properties, Application and change OutputType from Console to Class Library.
EDIT
Would like to express my doubts on architectual desicion like this, correct me if I'm wrong in my thinking:
Having different EXE applications standalone, I presume, you have different Applications that works standalone.
What advantage you gain by converting them in DLL's and puting them together in one master app ? Why do not just use this EXEs with one master app and launch them ?
In this way you leave as is it already working + you add a layer (master app) so for final user all this seems like one single app.
That is possible - several options:
you put the functionality of each console app into a separate class within the same project and have one "master console app" provide their functionalities
you put the functionality of each console app into a separate class each in different project with DLL as target, then you reference those DLLs as needed from your "master console app"
Note: IF you go the DLL route you could embed the DLLs into the console EXE using the technique from http://blogs.msdn.com/b/microsoft_press/archive/2010/02/03/jeffrey-richter-excerpt-2-from-clr-via-c-third-edition.aspx
With both option (all in one EXE or EXE + embedded DLLs) you can just make an XCOPY deployment if there are no other dependencies...

Categories