I searched the net for a really simple question. My solution is one exe (WPF) project and four class libraries. I need a logging and I like NLog. How can I use it from all of the 5 projects in one solution ?
I don't know, do I need to create (or get somewhere) a wrapper class project referenced from all of the projects and use Nlog from there ? I saw something like this written for log4Net.
Or is there some pattern or best practice for this scenario ?
Just reference NLOG directly in each of the projects and use it. But you only need to configure it in your main application. The configuration will then be shared automatically.
Related
We have started migrating to the new project type for .NET Standard and have used the tool that Hanselman linked in this blog post.
One peculiar thing we noticed is that a project now receives references to projects that it's references have. I have setup a sample and confirmed that it is not just our main application. For the main application, let's say we have
Console App: TestingSomeStuff
Net standard library: Library1
Net standard library: Library2
In this situation, we have the following references:
TestingSomeStuff -> Library1 -> Library2
For some reason, TestingSomeStuff, which does not directly reference Library2 is able to access types in Library2, and this just seems incorrect. I setup the same situation in a .NET Framework application and TestingSomeStuff does not have access to Library2.
In order to build an appropriately layered application, we need the ability to block TestingSomeStuff from accessing Library2 as a passthrough and I cannot find any information on how to approach that.
I have tried setting IncludeAssets, ExcludeAssets and other options similar to that but nothing has worked.
This is new to the new MSBuild projects for .NET Core. If you want to hide something, mark it as internal in Library2 and use the InternalsVisibleTo attribute and give Library1 access.
Alright, I figured out what was going on here, it was completely my mistake but I'm leaving the question un-deleted for the community. I was wrong in the statement that "ExcludeAssets" all did not work.
The issue was that the setup was more complicated than my sample project, Really what we had was:
TestingSomeStuff
-Library1
--Library3
-Library2
--Library3
I was only testing ExcludeAssets=All on Library1, so it was still referencing it through the reference to Library2.
I thought this would be dead simple to create a class library as Mydomain.Common
Then use this class library in my other projects libraries
MyDomain.OtherA
MyDomain.OtherB
I wan to use Mydomain.Common class library in both projects.
But I also want to use Mydomain.OtherA in Mydomain.OtherB project.
When I add the references and try to build the solution I get the error saying "eferenced assembly does not have a strong name".
I did read on answer on here but I couldn't make sense of it.
How can I achieve this?
I know that in many projects we use this approach to install nuget package in multiple projects and those projects also references another common project.
For example EF, Autofac, AutoMapper.
Is this not possible? Do I really need to sign the dll to use it in this scenario?
I have one windows service project. I want to convert that web service project into DLL. As a class library I can simply reuse those methods just by referencing that DLL.
I just want to know is there any simple way to do it or I have to manually create one class library project and reuse my code.
You can reference exe in other projects same as dll.
But moving this to separate class library is the best idea.
Just Click on the class library with the service code and select build. it will create a DLL file in your Debug folder in your project bin directory. You can use that DLL file anywhere.Hope this helps..
Just copy your code to class library project and built it. It will create .dll and you can easly use it by adding reference to your project. I think that would be a simplest approach
After searching and asking questions on ASP forums proper way of doing this is to manually reuse code.
I have created several small applications that use my own DLL. The problem is, this DLL is constantly changing. My current solution to this problem is that I have a Setup project in the class library solution that creates and registers the DLL. In all my applications I then have to open the solution and re-reference the newly created/registered DLL. Then I have to re-compile their setup projects, uninstall the old applications, and then re-install the new application.
There has to be a better way and I'm just not sure because I'm fairly new to all this. I have looked into ClickOnce but I don't think that will solve my issue as I cannot publish a class library. I have looked into checking version numbers but I must be doing something wrong because it doesn't work either.
I understand that once a DLL is created and being used in an application it should essentially not be touched. I do not have that option in this situation. It is constantly updated. Done.
So, is there a better way? A point in the direction of a guide or related question/answer/forum would be greatly appreciated.
Edit: The DLL is not constantly changing during runtime but it is constantly evolving to allow more functionality and detail within the other applications. Also, one big thing I guess I should have mentioned is the Public interface is constantly chaning - usually adding new methods.
Make sure the references to your DLL specify SpecificVersion=false. Then just deploy each new version into the GAC and that should do the trick.
Eventually, you can also manually force versions using Binding Redirection.
A solution you can try is to use a single solution for your project and reference the project wherever it needs to go.
Check out NuGet
You could set up an internal Nuget repository (really just a folder that stores nupkg files.) Then when you build a new DLL, you can update the apps as needed in studio. This would ensure it had the latest version. They shouldn't need a redployment unless there are bugs in the DLL that you're fixing.
One solution is as follows:
Physically separate the interface from the implementation. e.g. AssemblyA is the interface, the application (AssemblyB say) knows only the interface at compile time. The implementation (AssemblyC) also knows/references AssemblyA of course. The point being that AssemblyB does not reference AssemblyC. This will require you to use an IoC container (like MS Unity 2.0 but there are many others) in order to resolve and instantiate your concretes at runtime.
Write an update process that finds the new AssemblyC.dll, replaces the local copy and uses reflection along with the IoCContainer to 'load' the new implementation at what ever interval you require, typically app start up.
The above relies on your interface being stable. If it isn't, you may be able to write a (more) stable Facade.
(Sorry for might be a trivial question , I'm coming from Java & Maven , and still haven't wrapped my mind around C# dependencies )
I want to use log4net in all my projects. Since I don't want to add the dll to all the projects , I've created a "Globals" project , add a reference to log4net.dll in it , and referenced from all the other projects to the "Globals" project .
However , I can't seem to access the log4net classes from any other project .
using Globals.log4net;
Doesn't seems to work either .
What am I doing wrong?
If all you did was reference the DLL, then all you have done was get a copy of the DLL with every reference to your Globals project. You are still not using the library.
What I would normally do would create an ILogger interface, implement it using log4net in the Globals project and use that implementation in the other projects (plus a mock implementation for tests).
I'm afraid that's not how it works.
You have to add the DLL to all projects you want to call it from.
If you were only using a couple of functions in the DLL, you could create functions in your Globals project to call through to it.
log4net doesn't 'live' in Globals simply by the reference.
My 1st inclination would be to have all of your projects just reference log4net, it clarifies that there's a dependency there no need to hide it in another project.
However, if you do have common logic shared across your classes you could have a "Global" or "Common" class which includes references to shared libraries. To reference those libraries just add the using of the target namespace.
In other words, no matter if the reference is within the same project or another reference project, the using statement will be the same.
For log4net i believe it should just be:
using log4net;
The other way to add the proper reference would be to type one of the class names somwhere in your code ( Logger ? ) and then invoke the helper menu with "CTRL+." or by simply expanding it, this will have the option to add the proper using statement.
That system won't work. You'll have to add the log4net dll as a reference to all the projects. Or create proxy classes, which is much more work.
Read up on the GAC (Global Assembly Cache), this a central storage for DLLs that are shared across projects... thats where I put my log4net DLL. You can then simply add the reference to it in your .config file forevery project you need to use it in without adding the DLL to the projects themselves.
This is a good place to start: MSDN: Working with the Global Assembly Cache