I am creating some kind of a plug-in system. Currently I was using WinForms application to load the assemblies, using Assembly.Load and Activator.CreateInstance. The WinForms GUI was supposed to show only the names of the currently loaded assemblies (plugins).
There is a class in the library PluginManager, that instantiates and holds a list of all IPlugin implementors.
However, I now want to be able to access the list of plugins (their names only) from the Silverlight application.
I have a Silverlight 4 application created in Visual Studio.
This added two projects:
MyProject (SL 4 project)
MyProject.Web (containing the .aspx startup page which runs the .xap file)
What I need is for the PluginManager and its instantiated plugins to be loaded not only during the silverlight page request (thru aspx page), but all the time, even if the user never opens the silverlight app in the browser. And I am confused as to what is the entry point of the .Web project. (in console app, I would put the code into the Main method, in WinForms in Loaded event handler, but I don't know where to start my "service" in this .Web project).
How does this work? Where should I instantiate my PluginManager? Is that .Web project short-lived only during the HTTP request or can it be run continuously?
Add Global.asax to MyProject.Web. And do that in Application_Start() method.
This method invokes only once when application is built.
If you need to run your PluginManager before application has been built, you should create a windows service which runs from your installer. This service will instantiate PluginManager.
Related
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.
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.
I want to run a background task that will use a lot of the same code as the main project, so i have created a new project for my background task, and a new shared project for my shared code.
I have transferred all of my shared code to the shared code project, i have added the reference to my shared project into my main project and the project works.
I have then added a reference to my shared project into my background task project, built the solution and it works (works as in compiles).
As soon as i add the reference to my background task project into my main project, when i try to build the solution i get the following error:
A public type has a namespace ('BackgroundTask') that shares no common prefix with other namespaces ('SharedCode.Functions'). All types within a Windows Metadata file must exist in a sub namespace of the namespace that is implied by the file name. BackgroundTask C:\Users\User\documents\visual studio 2015\Projects\Project\BackgroundTask\WINMDEXP
If i dont add the reference to the background project within the main project and i try to run the background task, it fails.
In my background task project, at the top, i have included using SharedCode;
And when the task runs, it just needs to make one call to the shared code:
await SharedCode.Check();
The background task project, doesnt need to use SharedCode.Functions directly, that would be called from within the SharedCode project itself.
Any ideas?
And just for reference, the shared code will make a http request and update a local database using SQLite.net-PCL
It seems there is a base namespace rule for shared projects and Runtime Components. (I've never heard of this before.)
Because of the way code generated form a runtime component is exported it must have a single root namespace. The easiest way to achieve this is to use project names with a common prefix before a dot.
So instead of having projects called
MyApp
SharedCode
BackgroundTask
You call them (and set the root namespaces)
MyApp (or MyApp.Client)
MyApp.Shared
MyApp.BackgroundTask
As an alternative you may make things much simpler for yourself if you might instead be able to use an in-process background task (depending on what your task does.)
It seems that you are using an old 'shared' project template that was used on Windows 8 / Windows Phone 8.
In this kind of projects, the code is actually duplicated into the different parent projects meaning that even if you see three projects here, only two exe/dll will be generated. The code in the shared project will be copied into the windows and into the windows phone project.
To achieve what you are trying to do, you can simply create a regular class library (Universal Windows) to host your shared code, a Windows Runtime Component (Universal Windows) library to host the background task entry point and a Blank App (Universal Windows).
Both your background task and your app will reference the shared class library.
You can also leave all your shared code in the background task library (WinMD) and consume it from your application.
I have a windows form application, that when started in its constructor it generates some classes on the fly.
Is there a way which i can use, so that when i build or rebuild the project, some specific method gets called and thus generating my files without running the whole application?
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.