I am new to Azure WJs. I have 2 projects in one solution: the actual website - Project 2 and the WebJob - Project 1. The only task the WJ has is to call an exposed method from the public class of project 2 during the scheduled time.
When the WJ was created, the classes & methods of the Project 2 - website were added as a solution reference to the Project 1 - WebJob to make them accessible.
The problem I have is:
When the WebJob is build it compiles all the dependencies at the given time. When the final .zip is uploaded into Azure WebJob portal the webjob will execute with the compiled code version. This means that any new changes to Project 2 - website do not take effect until the WJ is re-build with the updated Project 2 - website dependencies and the .zip re-uploaded.
Is there a way to create WJ (as Project 1) which would call a specific exposed method from the Project 2 and be oblivious to the changes in the project 2 as long as the called method is present?
Example:
WebJob Code (project 1):
namespace SecondProject
{
class Program
{
static void Main()
{
var client = new WebClient();
secondProjectMethod();
}
}
}
Website Code (project 2):
namespace firstProject
{
public class someClass
{
public void secondProjectMethod()
{
// I want to make any code changes I want inside this
// method anytime and the WbJob should not care
// about these changes as long as this method name exist.
// Because all it should care about is that it should
// call this method name.
}
}
}
Since you are using a website, you can expose the method from Proj2 as an API, and make the WebJob invoke the API (instead of the method) at your scheduled interval. So even if you change the method in Proj2, as long as the exposed API is calling the updated method the WebJob will be independent.You can take a look at this link, for creating a basic API
at least two options come up in my mind:
Options 1: your WJ project do not directly reference your website project, instead, use reflection load the website dll in runtime. and use reflection to invoke the function you would like to call (assume signature will never change)
the challenge for this approach is your WJ somehow need to figure out the path to the website dll.
Options 2: since it is a website, why not expose the function you will like to call as a REST API, so your WJ just need to make a http call
The question doesn't seem to be a Web Job Specific one but anyways...
If you need the two projects to be independent, then you should not be using project references.
What I would suggest is to publish the Project2 shared class/methods as nuget packages and use the nuget instead, so any changes to the Project2 will not affect your WebJob until the point that you publish a new nuget package and use that your web job.
Alternatively you can have a folder for your dlls like "Shared Libraries" and reference the Project2 from that location instead of project to isolate the changes to your Web job from your Project reference..
Related
Requirement: I am trying to invoke a ADFV2 pipeline from Azure Function. The ADFV2 pipeline is already created through .NET api.
Problem: Not able to resolve Microsoft.Azure.Management.DataFactory (this one was introduced newly for ADFV2) nuget package where else the nuget package Microsoft.Azure.Management.DataFactories (this one already exists from the timeline of ADFV1) gets successfully accepted.
Error - Unable to resolve 'Microsoft.Azure.Management.DataFactory (>= 0.2.1)' for '.NETFramework,Version=v4.5.2'.
Why through Azure Function and not Trigger or Custom Activity: The ADFV2 pipeline is dependent on another process (the copy activity source dataset might not be ready when the pipeline will be scheduled to run) which could be achieved by .NET custom activity in ADFV2 itself but thought to try in the other possible way around.
Note: Already went through the link which talks about the same thing only difference being its ADFV1.
Answering and providing some other information so that others who might get stuck on situations like the above would get benefited.
So, finally was able to invoke ADFV2 pipeline from Azure Functions but for some reason was not able to add Nuget packages(Microsoft.Azure.Management.DataFactory) by referring them in project.json or using them directly in run.csx. So, uploaded the dll in bin folder and referred them in my function app as if they were external assemblies which worked fine for my application and was able to invoke all the ADFV2 pipeline related methods (ex: DataFactoryManagementClient, CreateRunWithHttpMessagesAsync etc...).
Also, just started working on VS2017 (version 15.6.0 preview 1.0) and checked the Cloud->Azure Functions application where managing the above mentioned Nuget packages is working smoothly.
I created a new ASP.NET Web Application project, using the "Empty" setting. This means I wasn't given any classes, and a fairly bare Web.config file. What file or config settings will I need to change to get a static class method to run when I first start the program?
Note: I tried adding a Startup.cs class with constructor, but that did not work, and I tried adding the <appSettings> tag with the child <add> tag specifying owin appStartup, but that did not work either.
It all starts with the global.asax. The IIS pipeline compiles global.asax, which usually references a global.asax.cs, which inherits from an HttpApplication. The application is then instantiated by the pipeline and its event handlers are called as pipeline events occur. The thing that sets everything off is the construction and Application_Start event of that application, where you compose the object graph, register bundles and routes, etc.
There is a lot more to it of course but that is where it all starts, if you want to try to reconstruct a working site yourself.
A very easy way to go about this, without needing to learn complicated IIS configuration, is to self host using ASP.NET Core.
First, install .NET Core: https://www.microsoft.com/net/learn/get-started/windows
Second, instead of following their steps to create a new console app, follow these command line instructions:
Create a directory for your project mkdir MyProject
Enter into that directory cd MyProject
Create a blank ASP.NET core app dotnet new web
Run it dotnet run
This will create and run a new blank ASP.NET web application which you can visit at http://localhost:5000
Two classes will have been generated: Program.cs and Startup.cs. Startup.cs will contain the logic for handling requests and serving responses, while Program.cs will contain the Main and BuildWebHost methods.
The server start code goes in the static Main method, allowing you to initialize anything you might want before the web server is even initialized.
An added bonus of using .NET Core is that you can run this not only on just Windows, but also all *nix systems as well (Linux, MacOSX).
I currently have a ASP.NET Core application implementing a basic web API. I have a need to write a script that hooks into the same environment with access to at least the database, but can't find a place to add new entry points to the application. I can easily look at string[] args in the Main method in Program.cs and not start the server, but I don't see how I can load up the environment and run arbitrary code without just standing up the normal Kestrel server. I'm pretty new to the .NET world so I'm hoping there is an easy way to do this that I've just failed to find in the documentation.
Basically I'd like to be able to run something like dotnet run foo which would execute some synchronous piece of code on the server instead of starting up the normal kestrel server.
You can do this by adding new projects. The idea is to have three projects co-exist in your solution:
the ASP.NET Core application, and
a .NET Core Console App containing your executable scripts, and
a .NET Class Library containing common dependencies of the two and containing service collection configuration, so that you can use the ASP.NET DI container from within your scripts
Steps to go from a single-project ASP.NET Core application to the configuration above (assuming that you're using Visual Studio) look something like:
Right-click your solution in Solution Explorer, go to Add -> New Project..., and select the project type Console App (.NET Core). Give it a name (e.g. Scripts) and click OK.
Add another project with type Class Library (.NET Core), named e.g. Common.
Migrate any classes that you want to use from the ASP.NET Core project to the Common project.
Add a CommonStartup class to your Common project. Give it a public static void ConfigureServices(IServiceCollection services) and cut and paste across any service configuration from your ASP.NET Core application's Startup.ConfigureServices method that you want to share with your Scripts project. Add a call to CommonStartup.ConfigureServices(services) to Startup.ConfigureServices method in the ASP.NET Core project. (You'll need to add references to Microsoft.Extensions.DependencyInjection; and Microsoft.Extensions.DependencyInjection.Abstractions; to the Common project and a reference to Common to the ASP.NET Core project; Visual Studio should offer these as sidebar actions.
At the start of your Scripts project's Main method, add:
var services = new ServiceCollection();
CommonStartup.ConfigureServices(services);
var provider = services.BuildServiceProvider();
(You'll once again have to add references.)
You can now use the DI system from within your Scripts project to get instances of classes, by writing e.g. var widgetFactory = provider.GetService<IWidgetFactory>().
You can build and run your script by running dotnet run from within the folder of your Scripts project.
If you want multiple executable scripts, just add a switch statement to your Main method that does something different depending upon the value of args[0], then call your scripts with dotnet run wibble, dotnet run wobble, etc.
I need to create a stand alone EXE of a solution. This solution contains two projects i.e:
A-project (set up as start)
B-project (A web services)
B-project uses a external DLL which is reside on same B-project folder.
Above solution runs perfectly after building it. Now i want to create a stand alone EXE. So that i can sell my product for commercial use (in my school).
To do this i have performed following points:
Add a new project(SETUP Project) in the solution with test name.
Now add project output and choose A-project from the project drop down.
Then i do the same for the B-project i.e. Add project output and choose B-project from the project drop down.
Check the .net framework 4 dependencies which was fine.
Build it.
Install it.
I went to the my program files directory and run test.exe with run as administrator, and try to open the web services URL.
I got to know that web services runs perfectly but when i enter the url it returns me Request error which happens when the method written in instance class didn't execute perfectly. In my project the method written in Instance classcalled the externall dll.
How should i link that dll with my EXE. so that it runs perfectly fine?
Should i change the path in code?
If you want to deploy one .EXE:
Add the dll that the Project B depend on as a Resource (right click on Add existing Item -> Select dll -> change build action to Embedded resources)
Do the same with Project A and Project B (i.e add them to your Setup.exe as Resources)
Then you need to implement the solution described here
How can I have code-sharing between two projects without making a dll?
The issue is: I have a tool that syncs users & groups from LDAP to a database.
Now the tool is a windows service, but testing it as such is very difficult and time consuming.
Which is why I made a console application where I can test the LDAP syncing, and then just copy the respective sourcecode-files over to the service project.
But... keeping the common files in sync is a bit of a problem.
I don't want to make a dll, because this probably creates me a problem with
the 3rd project, a windows installer (for the service) where I have to use ExecutingAssembly path...
Is there a way to share the code without making a separate dll?
Automagic statical linking, so to say ?
How about adding a file as a link.
In Visual Studio right click on your console test app project -> select add existing file -> in the file add dialog navigate to files in your actual windows service project -> select the files you want to share -> and on add button select add as link option.
You can add a file to a project as a link. On the Add Existing Item dialogue the Add button has a drop down on its right. Use this to select "Add as Link":
Put the file as a solution item and add as a link to each project.
How about hand-modify the project files to point to the same source file?
Another option - put both projects in the same folder. Add a class to one, then in the other project add existing class and point to the class just created.
You could:
maintain the shared code in a separate project that produces a DLL and then use a tool such as ILMerge to turn the DLL & EXE into one assembly.
share the source-files between multiple projects, either by tweakiing your project files or doing something funky with your source-tree layout.
All that said, the best approach would be to bite the bullet and store the shared code in a shared assembly (DLL). What happens when you decide to, for example, expose this code via a WCF service? It starts getting more complicated then as you have 3 places that reference the same code files. Don't just think about what makes your life easiest now, think about what'll make your life (and that of anyone else who has to maintain the code) easier in the future as well! =)
Necromancing - As per Visual Studio 2017:
You can create a shared project, and then reference the shared project in another project.
It will use the framework-version and libraries from the project you reference the shared-project from. You can also use the same shared project in multiple projects, provided you get no conflict.
This is basically statical linking on a source-code level.
This also works with HTML&JavaScript-files (specifically, it works with publishing), but with HTML & JS files, you will run into problems while debugging...
It's under "Classical Windows Desktop", but you can also use it for .NET Core etc.
If you want to share functionality, you should use a DLL or similar.
Since what you want to share is the source, what you are essentially sharing is file sharing. So you can do that by making your projects reference external sources or you can have your source control do this for you.
If you are using Visual SourceSafe, you can make a link between two folders. VSS will make sure that they are treated as the same file.
I'm going to describe the setup we use to manage and test our Windows Service projects. While this doesn't answer the question of "sharing code without a DLL" (Unmesh's answer takes care of that), I think the OP probably doesn't realize how easy this is with a DLL. In any case, I'm hoping it will help someone.
Create a solution, LDAPSync. Create three projects in this solution:
LDAPSyncLib
LDAPSyncSvc
LDAPSyncTest
LDAPSyncLib is a DLL project that contains all of your business logic and main functionality.
LDAPSyncSvc is a Windows Service project that contains two classes, a service controller class that inherits from ServiceBase, and an Installer class for your service. This project has a "project reference" to LDAPSyncLib.
LDAPSyncTest is either a GUI application (WinForms, WCF, etc.) or a console application, depending on your needs. This project also has a "project reference" to LDAPSyncLib. Its sole purpose is to provide some interface which allows you to easily make the required calls into your business logic for testing purposes. In Visual Studio, set this as your "StartUp Project".
Now, when you run in debug via Visual Studio you will get a nice little GUI or command window that you can use to manually make test calls. When you install it as a Windows Service, the LDAPSyncSvc project's controller class will take over and handle all of the necessary service requests (start, stop, pause, etc.)
We have around 30 in-house Windows Service projects that we've been continuously managing, developing and testing for over a decade and this workflow has proved invaluable in quickly finding and fixing bugs when they arise. Best of luck with your project and I hope this helps some future Googlers.