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.
Related
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.
Am trying to create a WCF project by following the walkthrough here ... http://msdn.microsoft.com/en-us/library/bb386386.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-3, but got stuck at the first steps.
Bad - VSE Windows Desktop does not have the WCF service library templates.
Good - VSE Web Developer does, so I set up the WCF project in VSE Web Developer
Bad - Cannot open the WCF project in VSE Windows Desktop
Good - Find out that you can copy templates from VSE Web Developer Folders to VSE Windows Desktop, and I do
Good - VSE Windows Desktop now has WCF service library templates, so I try to create a new WCF project. VSE seems to comply, sets up the project folder ... but then
Bad - ... throws the error ...
The project file '... WcfService1.csproj' cannot be opened.
There is a missing subtype.
Subtype:'{blah blah}' us unsupported by this installation.
I even tried turning it off and turning it on again.
What next?
As I mentioned in my comment, a WCF Service Library is nothing more than a class library - the WCF Service Library project template just has additional stuff to make it quicker to set up the project. You can do the exact same thing by creating a class library.
Go to File -> New Project on the menu. In the window that opens up, expand Visual C#, then select Windows and select Class Library from the list in the center, give it a name and then click OK.
You'll have to add the Interface and the config settings for the service, but you should be able to copy and paste from the article you're following. Once that is done, voila, you have a WCF Service Library.
Edited for more details
The only thing the WCF Service Library template gives you is a boilerplate for a WCF Service Library - that includes the .cs file for the service implementation, the .cs file for the service contract (interface) That the service implements and an app.config file that has the necessary <system.serviceModel> entries.
Sticking with the article you linked to in your original post, here's how to do this without the template.
Step 1 and 2. Follow what I had above - create the class library. VS will create the project and you will see a file named class1.cs. This will be your service class. Rename it to WCFServiceLibrary1.cs if you desire.
Next add an interface and name it IWCFServiceLibrary1. This will be your service contract. You will need to update the WCFServiceLibrary1.cs file and add : IWCFServiceLibrary1 after the public class WCFServiceLibrary1, so it looks like this:
public class WCFServiceLibrary1 : IWCFServiceLibrary1
In the interface, add the [ServiceContract] attribute above the interface, like this:
[ServiceContract]
public interface IWCFServiceLibrary1
You will also want to add a reference to System.ServiceModel and using System.ServiceModel to your class and interface.
Step 3 and 4. Copy the code in the article to the proper files.
Step 5: You can test the service by hitting F5 and running the WCFTestClient.
You should then be able to follow the rest of the article.
It takes a little longer this way, but you will also gain a better understanding of what the WCF Service Library is.
Expectation management - I was expected to go through all the steps in the walkthough, but they might not be necessary (which is implied in the answers given). So, I tried a bare-bones set up, described here ...
Is it possible to start exploring WCF using Visual Studio Express for Windows Desktop 2013?
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.
I have WCF service developed in C# for with .NET framework 4.0 for IIS v7. My service using some managed VC++.NET DLL's which internally relies on some native C++ DLL's.
Now I have following options to proceed;
1) Publish all my managed DLL's in GAC (Global Repository)
2) set PATH environment variable, re-start my machine so that IIS (7) server can pick up the changes.
But client does not want both of the above solution because of following reasons;
1) They do not want anything available globally
2) Setting PATH, re-start the machine for every service deployed....NAAAAAH!!!!
So I researched and then I found I can set the environment on runtime, so I added some properties within my Web.config file and thought of appending my environment for each service on runtime. But the problem is that where should I write this peace of code as if I append this code in service class IIS will fail as it will try to resolve all the dependencies but fail as my code is not ran yet.
Now I want, a way to split my code which set up the environment in separate class for each service on startup of the service and called that in the end when we un-deploy.
I am not sure if it is even possible?
P.S Please bare in mind I am new to WCF and .NET stuff.
Your help and comments will be appreciated.
--
SJunejo
If yout don't set the Delay Load Property all referenced unmanaged DLLs will be loaded before your global.asax code is executed, so it's still looking in the wrong place.
You should follow all steps in Option 2b) if you want it to work.
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.