Wrapper for Common Logging based on NLog? - asp.net-core

We want to use a common logging library for ASP.Net Core web applications, Azure Functions and Web Services. NLog seems like a good option since it has multiple targets e.g. Application Insights and Azure Table Storage. Ideally, I'd like to do something like call CommonTrace(message) and have that function
(1) track other information such as (a) Environment - DEV, TEST, PROD; (b) the local time, (c) System.Runtime.CompilerServices.CallerLineNumber (d) calling application etc.
(2) Call NLog to write out the message and other information. Note the other information may be prepended to the message or persisted in some other way.
But as I learn more about NLog and ASP.NET Core, it seems that if one naively creates a basic wrapper class to add additional information, one could lose out on a lot of features e.g. accessing the callsite and header information that NLog and Microsoft.Extensions.Logging provides.
So, is it possible to subclass NLog entirely and then use that wrapper as one would normally use NLog with ASP.Net Core. Or is there a better way to add common information from multiple applications when using NLog?

NLog has the ability to capture lots of context properties, without them being injected directly with the log-operation.
They are captured automatically by the Layouts configured for the NLog-target. Some NLog targets allows one to add any number of properties.
This can be seen with the NLog Application Insight Target (ver. 2.6.4), that now has the ability to add one (or more) "ContextProperty"-elements. These will automatically be included as meta-data with each log-operation:
https://github.com/Microsoft/ApplicationInsights-dotnet-logging/pull/183
If the NLog target doesn't have support for ContextProperty, then one can also turn to the NLog JsonLayout that allows one add metadata as additional Json-Attributes:
https://github.com/NLog/NLog/wiki/JsonLayout
If your favorite custom NLog target supports structured logging properties, then it should be a small change to add support for ContextProperty-elements (Easy way is to inherit from NLog TargetWithContext and just use GetAllProperties-method):
https://github.com/AlanBarber/NLog.Targets.Splunk

Related

Zend Framework 3 singletons

I'm creating a new application in Zend Framework 3 and i have a question about a design pattern
Without entering in much details this application will have several Services, as in, will be connecting to external APIs and even in multiple databases, the workflow is also very complex, a single will action can have multiple flows depending on several external information (wich user logged in, configs, etc).
I know about dependency injections and Zend Framework 3 Service Manager, however i am worried about instanciating sereval services when the flow will actually use only a few of them in certain cases, also we will have services depending on other services aswell, for this, i was thinking about using singletons.
Is singleton really a solution here? I was looking a way to user singletons in Zend Framework 3 and haven't figured out a easy way since i can't find a way to user the Service Manager inside a service, as I can't retrive the instance of the Service Manager outside of the Factory system.
What is an easy way to implement singletons in Zend Framework 3?
Why use singletons?
You don't need to worry about too many services in your service manager since they are started only when you get them from the service manager.
Also don't use the service manager inside another class except a factory. In ZF3 it's removed from the controllers for a reason. One of them is testability. If all services are inject with a factory, you can easily write tests. Also if you read your code next year, you can easily see what dependencies are needed inside a class.
If you find there are too many services being injected inside a class which are not always needed you can:
Use the ProxyManager. This lazy loads a service but doesn't start it until a method is called.
Split the service: Move some parts from a service into a new service. e.g. You don't need to place everything in an UserService. You can also have an UserRegisterService, UserEmailService, UserAuthService and UserNotificationsService.
In stead of ZF3, you can also think about zend-expressive. Without getting into too much detail, it is a lightweight middleware framework. You can use middleware to detect what is needed for a request and route to the required action to process the request. Something like this can probably also done in ZF3 but maybe someone else can explain how to do it there.

ASP.NET 5/MVC 6 area functionality in multiple projects

We are building a very large web site that will consist of a main site with many sub sites. These could typically be implemented in areas, but the development cycle and teams for these sub sites are disparate. We want to be able to deploy only a single sub site without taking an outage for the entire thing. We are trying to determine if there is a good, clean way to have a project for the main site and projects for each sub site.
In this case, the main site has all the core layout and navigation menus. The user experience should be that of a single site. Ideally, the sub site projects could be used just like areas in MVC utilizing the layout pages and other assets from the main site.
While I think this is doable by patching things together on the server, there needs to be a good development and debugging story. Ideally, the main site and a subsite could be loaded into Visual Studio for development. Additionally, it would be nice to be able to do a regular web deploy without duplicating core files in each sub site.
Like I mentioned, we could use areas, but would like to know if there are other viable options.
Answers to questions:
The sites will probably will reuse some contexts and models. Do they share the actual objects in memory, I don't think so. Each would have their own instances.
There will be several databases partitioned by domain. One for the core site and several more, as many as one per sub site. For example sub site A might need to access some data from sub-site B. This would be handled via a data or service layer.
The site URLs would ideally be as follows:
Core site: http://host
Sub site A: http://host/a
Sub site B: http://host/b
Specific things to share: _layout files, css, js, TypeScript, images, bower packages, etc. Maybe authentication, config, etc.
The authorize attribute would be the preferred approach. A unified security infrastructure that behaved like a single site would be the best option. Not sure if that is possible.
This seems like a good architecture question. I wouldn’t know how to properly answer your question since I’m no architect and also because it seems to raise more questions than answers...
Assuming a typical layered application looks somewhat like this:
Contoso.Core (Class Library)
Contoso.Data (Class Library)
Contoso.Service (Class Library)
Contoso.Web.Framework (Class Library)
Contoso.Web (asp.net MVC application)
For now, I’m disregarding the fact that you want this in asp.net 5/MVC 6.
Contoso.Core:
This layer would hold your entities/pocos in addition to anything else that may be used in the other layers. For example, that could be Enums, Extension methods, Interfaces, DTOs, Helpers, etc...
Contoso.Data:
This layer would be where you’d store your DbContext (if you’re using EntityFramework) and all the DbSets<>, it would also hold the implementation of your repositories (while the interfaces could be living in the Contoso.Core layer...you’ll see why later).
This layer has a dependency on Contoso.Core
Contoso.Service:
This layer would be your Service layer where you define your services and all the business rules. The methods in this layer would be returning Entities/Pocos or DTOs. The Services would invoke the database thru the repositories assuming you use the Repository Design Pattern.
This layer has a dependency on Contoso.Core (for the entities/pocos/dtos and for the Interfaces of the repositories since I assume you’ll be injecting them). In addition, you’d also have a dependency on the Contoso.Data layer where the implementation of your repositories lives.
Contoso.Web.Framework:
This layer would have a dependency on Contoso.Core, Contoso.Data and Contoso.Service.
This layer is where you’d configure your IoC Container (Autofac, Unity, etc…) since it can see all the Interfaces and their implementation.
In addition, you can think of this layer as “This is where I configure stuff that my web application will use/might use”.
Since that layer is for the web layer, you could place stuff that is relevant to the web such as custom Html Extensions, Helpers, Attribute, etc...
If tomorrow you have a second web application Contoso.Web2, all you’d need to do from Contoso.Web2 is to add a reference to Contoso.Web.Framework and you’d be able to use the custom Html Extensions, Helpers, Attributes, etc...
Contoso.Web:
This layer is your UI/client layer.
This layer has a dependency on Contoso.Core (for the entities/pocos/dtos). It also has a dependency on Contoso.Services since the Controllers would invoke the Service Layer which in turn would return entities/pocos/dtos. You’d also have a dependency on the Contoso.Web.Framework since this is where your custom html extensions lives and more importantly, where your IoC container is configured.
Notice how this layer does not have a dependency on Contoso.Data layer. That’s because it doesn’t need it. You’re passing by the Service Layer.
For the record, you could even replace the Contoso.Service Layer by a WebAPI (Contoso.API) for example allowing you to create different types of applications (winform, console, mobile, etc...) all invoking that Contoso.API layer.
In short...this is a typical layered architecture you often see in the MVC world.
So what about your question regarding the multiple sub sites? Where would it fit in all of this?
That’s where the many questions come in...
Will those sub sites have their own DbContext or share the same one as the Main site?
Will those sub sites have their own database or the same one as the Main site? Or even different scheme name?
Will those sub sites have their own URL since you seem to want the ability to deploy them independently?
What about things that is common to all those sub sites?
What about security, Authorize Attribute and many more things?
Perhaps the approach of Areas and keeping everything in one website might be less error prone.
Or what about looking at NopCommerce and using the plugin approach? Would that be an alternative?
Not sure I’ve helped in any way but I’d be curious to see how others would tackle this.
You need an IIS website configured in your dev machine. You can automatize its creation with VS Tasks. You can have also a task to build and publish your solution there as well. This will take some time, but you'll have the advantage it could be reused in your CD/CI build server, with proper configuration.
After creating your main web project in your solution, create a subsite as a new web MVC project, naming it in a way that makes sense. For example, if your main web project is called MySite.Web.Main, Your subsite could be MySite.Web.MySubsite.
Delete global.asax and web.config from all your subsites, and there you go. Once published, all your subsites will rely on the main site global.asax and web.config. If you need to add configuration changes to your main web.config from your subsites, rely on web.config transformation tasks to be triggered after the build complete successfully. You can have different transform files for different environments.
Remember that you'll need to add all that automation to your CI/CD build server as well.
NOTE: when you add a new nuget dependency on your subsite projects, there is a chance it'll create a new web config. It's crucial that all subsite web.configs are either deleted or modified in a way that their "Build Action" property is set to "none", or it'll override the main web config during the publication process. One way to work around this is, instead of deleting the subsite web.config, you delete its content and set "Build Action" to "none" as soon as you create the project.

Replacement Implementation for Provider Model in ASP.NET 5

I have existing code that uses System.Configuration.Provider namespace for provider collections to plugin various implementations of interfaces, where multiple implementations exist in the collection and are selected by name according to various logic.
This namespace is not available in .net core, so I'm looking for advice on how to implement a replacement solution that will work with .net core framework.
I know that if I was just trying to plugin one implementation, I could do it by dependency injection. But I'm looking for a way to have multiple implementations available to choose based on name.
My current implementation with provider model populates the provider collection from a folder where you can drop in xml files that declare the type of the actual implementations, so new implementations of the provider can be loaded from an assembly by just adding another file to the folder. I'd like to keep the logic as similar as possible to that but I'm open to json files rather than xml.
I am thinking I could load up a collection of implementations of the interface from json files in Startup and use dependency injection to provide the collection where needed or perhaps an interface that can get the collection would be lighter weight and allow getting them when they are needed rather than at startup.
Is that the right approach? Anyone have better ideas or done something similar?
This is done more generically than using an abstract base class like ProviderBase in the new framework. You can register multiple of the same service with the DI framework and get them all either simply by asking for an IEnumerable<> of the type you register them as or using the GetRequiredServices<> extension method. Once you get your services, however, you'll need some other way of distinguishing them, such as a property indicating a unique name, which is the pattern the ASP.Net team has been following.
You can see an example in the Identity framework v3 with the Token Providers.
IUserTokenProvider<T>, the "provider"
UserManager, which consumes the token managers

Problem with WCF and multiple namespaces - sharing object types across multiple service references

i have two web services. One with user functionality, one with admin functionality.
Both services effectively work with the same object types, for instance:
AdminService provides functionality for deleting/modifying Customer objects
UserService provides functionality for listing/reading Customer objects
Now in the client i have two service references, Webservices.Admin and Webservices.User.
If i use the UserService to retrieve Customer objects, i cannot manipulate those via the AdminService, since the UserService retrieves objects of type Webservices.User.Customer, however the AdminService works with objects of type Webservices.Admin.Customer.
On the server side both types are identical, just belong to different namespaces in the client.
Now the question: How can i share types across different service references?
Check out https://github.com/geersch/WcfSvcMap
By tweaking the Reference.svcmap file you can make sure only one class is generated for each DataContract used by the different service references.
Note: Remember to delete the content of the node before pressing 'Update Service Reference'
If you're controlling both ends of the communication, and both ends are .NET only, you could do this:
put all your contracts, including your data contracts, into a separate "Contracts" assembly
reference that assembly in both the server side implementation code, as well as the client side code
If you do this, when adding the service references, WCF will find and use that shared assembly, and not create new types for the entitites. In your case, you'd only ever have one type Contracts.Customer or whatever you're dealing with.
This works only if you control both ends of the wire and have .NET on both ends! But in that case, it's a great way to share contracts - especially data contracts - across both the server and any number of clients.
Use the slsvcutil to create the WCF proxy on the clientside (assuming the clientside is a .net application), reference the DLL which contains your objects and it will be used for all endpoints that pass the same object in the DLL
Open Visual Studio Command prompt from the Start -> Visual Studio 2008 -> Tools -> Visual Command Prompt
goto directory similar to
C:\Program Files\Microsoft SDKs\Silverlight\v3.0\Tools
type slsvcutil and follow the syntax
slsvcutil http://somewcfservice:8080 /r:CommonLibrary.dll
where CommonLibrary.dll is the dll that contains the business objects
[edit] fixed the fact that the project is a silverlight project
There is an easy way to share types between client and service, just by adding reference to shared type assembly to your client BEFORE adding the service reference.
You can find the detailed scenario and sample project there:
http://blog.walteralmeida.com/2010/08/wcf-tips-and-tricks-share-types-between-server-and-client.html

WCF service reference update

Right now we have around 5 service reference added to our projects in a single solution.
I am force to add service reference even for projects having indirect dependencies calling service methods. Is there a way to get around for this situation.
For every single change in the service method, I have to update every single service reference to effect those changes. It is very time consuming too.
I am just wondering, is there any way i cam manage these things globally by making single service reference for the whole solution.
help appreciated.....:)
You should be able to use the svcutil.exe command line utility to generate a single service file (.cs file for example) from multiple service URL's. The nice thing about this is that you can share clinet-side DTO's and message types accross services if they have the same schema.
SvcUtil Reference: http://msdn.microsoft.com/en-us/library/aa347733.aspx
In regards to the requirement of adding the service reference to projects with indirect dependencies. You should probably not consume the service reference and related types directly from your service client. To improve maintainability and adaptability, you should wrap your service reference(s) in a facade. The facade would map between local types and service reference types, and give you much more agility in terms of responding to service changes. You would then only need to have the service references in a single location (preferably an independent project) along with the facade. The facade, which should change infrequently, will buffer you from the issues you are currently having with your service references.
You won't be able to get a single reference if you have multiple service, unfortunately.I stand corrected - see jrista's answer.
What you could do is create and update the service references automatically: instead of adding them manually in Visual Studio using Add Service Reference check out the svcutil.exe command line tool which will basically do the same thing.
Since it's a command line tool, you can have it run as e.g. part of your continuous build and update the necessary proxy client files every time you build the app.
Check out these additional links for tutorials and explanations about the details of using svcutil.exe:
http://msdn.microsoft.com/en-us/library/ms734712.aspx
http://asadsiddiqi.wordpress.com/2008/10/25/how-to-generate-wcf-client-proxy-class-using-svcutilexe/
http://www.xvpj.net/2008/03/08/wcf-step-by-step-tutorial/
Marc