Best pattern for configuration management Asp.net - c#

I always see that there are app.config's in dlls and then website has web.config.
At the run time mostly web.config passes data to all the portable libraries.
These configuration are passed as properties of portable library class. ConfigurationManager is used to get the values from config file.
Now the problem, In my current project they have configsectionhandler in webapp project/folder.
and my project folder structure is like
Main
WebApp
BusinessObject
ThirdPartyWebserviceCall
and as usual webapp project has reference to BusinessObject and BusinessObject has reference to ThirdPartyWebserviceCall.
Now if I want to use configsectionhandler in ThirdPartyWebserviceCall I will have add a circular reference to
webapp.
Does this design seem ok? It looks realy flawed to me.
Is there other standard pattern to access configuration values in the libraries.

Related

Do binding redirects in app.config for class libraries do anything?

The VS solutions I often work with consist of a single executable project (console app, web app) and many class library projects that are all referenced by the executable.
When working with NuGet and installing packages, there's often an app.config file created for each project, usually containing nothing else than a list of binding redirects that consolidate versions of referenced assemblies. Sometimes there's some third-party library-specific content (like Entity Framework config section), but let's leave that aside for now.
When I build the solution and use the binaries of the main executable project, I see all the class library project assemblies in the build output together with the corresponding *.config files (the app.config file gets renamed to AssemblyName.config when built).
When launching the main executable, do the config files of the class library assemblies take any effect? Or is it just the app.config file of the executable that has an effect in this case? What if there are some binding redirects set up on some of the class library projects, and some different binding redirects set up on the main executable project — How are these combined, which take priority?
I've tried to research this online and from what I've read, it looks to me like the app.config files for non-executable assemblies are useless (with regards to binding redirects). Can someone confirm this or elaborate a bit more on the topic?
If it is that way, is it actually undesirable to have these app.config files created by NuGet in class libraries if they contain just the binding redirects? It feels to me that NuGet shouldn't create those binding redirects for class library projects, as it will only increase the confusion about what settings are actually applied.
I found these existing Stack Overflow questions on the topic, but their accepted answers are actually contradictory even when they're marked as duplicates of each other.
Why NuGet adds app.config with assemblyBinding to LIBRARY projects during a NuGet package update?
Is the bindingRedirect .config file needed or all assemblies in an application?
The accepted answer to the first question mentions that app.config files are actually used during compile-time, which means they could have effect. Sources like MSDN and MSBuild source code are cited there as a proof it's used during compile-time. Unfortunately, I'm not proficient enough in MSBuild to understand how it's being used, and if it's really a valid argument.
Can anybody describe an example scenario to prove that an app.config with binding redirects for a class library can do anything?
I have multiple applications with similar setup - Web application referencing multiple library projects each having their own nuget packages etc., Based on my personal experience the assembly bindings in the library projects are not considered during run time.
The bindings specified web or app config in the root application (web/console) is that only matters. All my library projects are setup with "Copy to Output Directory" setting as "Do not copy" for the app.config file - that way my output folder is not cluttered with dll and their config files.
Here is the link which says how the assembly is loaded and where is it being searched and the sequence of it. No where in the article they talk about individual project config files.
Hope that helps.
According to this old msdn article:
An application configuration file is an XML file used to control assembly binding. It can redirect an application from using one version of a side-by-side assembly to another version of the same assembly. This is called per-application configuration. An application configuration file applies only to a specific application manifest and dependent assemblies. Isolated components compiled with an embedded [ISOLATIONAWARE_MANIFEST_RESOURCE_ID] manifest require a separate application configuration file. Manifests managed with CreateActCtx require a separate application configuration file.
So only dll's with the ISOLATIONAWARE_MANIFEST_RESOURCE_ID set actually use an independent application config, otherwise it's deferred to the main process config file.
For more info on what ISOLATIONAWARE is you can read this other MSDN article that goes more in depth.
ISOLATIONAWARE_MANIFEST_RESOURCE_ID is used primarily for DLLs. It
should be used if the dll wants private dependencies other than the
process default. For example, if an dll depends on comctl32.dll
version 6.0.0.0. It should have a resource of type RT_MANIFEST, ID
ISOLATIONAWARE_MANIFEST_RESOURCE_ID to depend on comctl32.dll version
6.0.0.0, so that even if the process executable wants comctl32.dll version 5.1, the dll itself will still use the right version of
comctl32.dll.
The answer is maybe. Depending on the type of project the library file is. Some library projects run in contexts where the library's config file is respected (e.g. Azure Web Roles), but that is not the norm.
See my answer here for more details.
Generally there is only one configuration file and thats the configuration file of the executeable (.exe.config, web.config).
Any assembly redirects have to be placed in the configuration file of the executable.
Configuration files of dlls need to be loaded manually using the ConfigurationManager class. See also this question Equivalent to 'app.config' for a library (DLL)
No, only the app.config of the executable will have effect. For example, if you have a console app hosting a WCF service, and in your WCF service you make use of, for example, ConfigurationManager.AppSettings, the AppSettings will come from the console host app.config file. If you spin up another console application (ConsoleClient) to try connecting to the ConsoleHost, then in the parts where the ConsoleClient can be said to be "executing" (for example in its main method), it will use ConsoleClient's app.config, but as soon as it begins using the WCF service, the WCF service will delegate to use ConsoleHost's app.config. (Note that this last point is more relevant to the details behind WCF though.)
Surprisingly, msdn provided this great source:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/e13194df-6308-4cbe-973c-f6a462f43eae/how-can-wcf-library-dll-access-application-settings?referrer=http://social.msdn.microsoft.com/Forums/vstudio/en-US/e13194df-6308-4cbe-973c-f6a462f43eae/how-can-wcf-library-dll-access-application-settings?referrer=http://social.msdn.microsoft.com/Forums/vstudio/en-US/e13194df-6308-4cbe-973c-f6a462f43eae/how-can-wcf-library-dll-access-application-settings?forum=wcf

How to create/use Configuration File for Infrastructure Layer (Class Library) Project in Domain-Driven Model

In my Domain Driven Layers, Infrastructure Layer Project is class library Project which needs to use a configuration file for not only connecting to database but also to create Repositories and Entities. However, the links (mentioned at the end of post state that class library project cannot have a configuration file (I think, class library cannot have a app.config).
My Question is that if not then how to create and use a configuration file for my Infrastructure Layer (Class Library) Project ? under which Project and what should be the naming convention ?
DETAIL:
I am following a book on Domain Driven Design in C#.NET. In this model (Visual Studio Solution), there four layers (each project in Visual Studio as layer) named below:
Presentation Layer Project (WPF, not .NET class library)
Application Layer Project (.NET class Library)
Model Layer Project (class Library)
Infrastructure Layer (.NET class Library)
Infrastructure Layer Project (as .NET clas Library) needs to use a configuration file, in order to:
A) Create Repository (using Repository Factory),
B) Create Entities (using EntityFactoryBuilder),
C) Connecting to database.
For this i created configuration file under the project "ProjectName.Infrastructure" as "ProjectName.Infrastructure.config" by setting its property (using Visual Studio) "Copy to Output Window" as "CopyAlways".
However, according to some posts (links at the end):
"a class library project (like my "Infrastructure Layer Project") cannot have a configuration file (application configuration file OR app.config file) instead a calling application should supply/provide configuration file and that class library use this provided file".
Links ( That i researched on):
How to access a custom config from my class library application?
and
http://msdn.microsoft.com/en-us/library/ms229689.aspx
The idea is to keep configuration file on client side (Application OR Presentation Layer level), not on server side (class library or DLL), Why ?
Bacause, purpose that a class library/dll (Infrastructure Layer/Project) serves is to be shared among more than one Clients (Presentation Layers OR Software Applications), each client (Software Application) configured with its own configuration setting that can be used (at run time) by the Class Library (.NET's ConfigurationManager class of Syste.Configuration ensures provision of Configuratio of calling/client application to class library so class library can use ConfigurationManager to use calling/client software's configuration).
In other words, it is duty of Presentation Layer to supply its configuration setting (in its App.config file) so that Class Library (DLL) access these configuration settings (residing in App.config file of the specific client) on the fly (;at run time), if needed, using ConfigurationManager class (of System.Configuration).
I see it very useful in that every application will have its own configuration whereas class libary will be able to access the caller's/client's configuration through .NET System (System.Configuration) as described above.
(Note: I somwhere read that class library can have its own configuration also (probably for its own internal use) however class library's internal configuration setting is not related to App.Config, i think)

Referenced Projects and Config Files

I am a bit confused on this subject.
The situation I have is I have two separate projects in C#:
are service (A)
a helper project (B)
Both are in seperate solution files. (A) has reference (B)
What i am confused about is that e.g. I have app.config file in (A), so when I refer to:
ConfigurationManager.AppSettings["XYZ"]
in project (B). does that mean I am using project (A)'s app.config file?
Yes, the ConfigurationManager class and the underlying configuration file is available to the whole AppDomain instance. Since your library will be getting used by the service, it becomes part of the service's AppDomain and inherits access to that configuration file.
If you want the other binary (project B) to have it's own, then you need to create an instance of it in it's own AppDomain. It's more trouble than it's worth, so I wouldn't try to look into doing this.
Any AppDomain that will use this library will be providing it's config settings. This means that if the library has it's own settings the service itself does not use, then you need to ensure any executable that uses the library has the settings present.
So if you have a solution that has ProjA (Console app), ProjB (WinForms app), and they both use ProjC (shared library), make sure the settings ProjC is looking for are in both ProjA and ProjB's config files since ProjA and ProjB are their own AppDomain instances when run.
The answer to your question is YES
And another point to note here is that the app.config file of your main project is always deployed (not the referenced project) unless you explicitly copy the app.config of referenced project. Therefore it is always better to do all your work on app.config of your main project which in your case is A
If i understand correctly you have two projects in ur solution
Project A (WebService)
Project B (Class library)
if that's the case - Yes. ConfigurationManager.AppSettings will read from the config file of the startup project i.e Project A in ur case.
However if you have different project which run independently for e.g. two different service projects Service1 and Service2 both will refer to their respective app.config/web.config files.

Inject dependencies (NLog) into dynamically loaded types

I have sort of plugin architecture in my solution.
There is a well-known folder where to place plugins in it.
The plugins implement an interface which is shared in the host project.
Initially i load the plugin via Assembly.LoadFrom(fi.FullName).GetTypes()
and instanciate the needed type by (IPlugin)Activator.CreateInstance(type);.
So the host (main application) can execute appropriate code implemented by the plugin assembly. This works fine so far.
But recently i tried to implement application logging via NLog and configured NLog in the host project which worked great.
The problem is i would like to use (the already configured) logger in the plugin assembly.
If i just reference NLog and use it by LogManager.GetCurrentClassLogger(); there seems to be no configuration set. It does not log to the files i configured in the host project out of the plugin assembly.
I thought of trying to inject an NLogger instance (created in the host project) to a property of the plugin type.
Is this possible or is there a preferred way to accomplish things like that?
Thanks
this should work - NLog configuration should work also for the loaded plugin assemblies.
The problem is probably related to how your plugins are loaded. Maybe they are in a separate domain (I don't remember how it works) so NLog can't access your main applications's logging configuration.
In that case you could try adding separate nlog configuration files for your plugin assemblies (read nlog documentation about config file naming conventions).
I dont think IOC container will help you in case of dynamically loaded plugins - the container will not know about them so you will have to change the way plugins are loaded and configured. And imho using IOC for configuring nlog is not a great idea.
If the previous options don't work you could try changing the assembly probing path in app.config so your plugins are loaded into the default domain - then NLog should work for these plugins (at least works for me):
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="Plugins" />
</assemblyBinding>
Have a look at Dependency Injection Containers like Unity or Lightcore.
They are some kind of "component registration stores"
there you can register components to interfaces. Then your consumers just need to request an interface.
The mapping of interface - component can be made in configuration files or source code.
So you can change the mapping without any pain.
For example when they are creating new instances and you are having complextypes as ctor parameters, they can make an automatic lookup if these components are registered and then inject them automatically.
Some Keywords that can help you are "ServiceLocator" "MicroKernel" "Depency Injection"
Components:
Lightcore
Unity
Also a more Plugin centric way is MEF

Including a service reference from a class library

I have a C# class library and a startup project (a console app). The class library includes a service reference to a web service. When I try to run the project, I get an InvalidOperationException because the startup project isn't reading the class library's app.config, and it's ignoring the service reference. To get it working, I'm forced to add the same service reference to the startup project. Is there any way I can avoid this? Can I make the startup project recognize the class library's service reference and app.config without having to copy it to the startup project?
I've tried adding a link to the app.config from the class library, but that doesn't work. The class library isn't very portable if it requires anyone who uses it to add that service reference to the startup project.
Think about what you are trying to do - you have two assemblies that you are building:
Library
ConsoleApp
Both of these assemblies have configuration files - I would imagine they look something like this:
Library
app.config
ConsoleApp
ConsoleApp.exe.config
When you run ConsoleApp it has no way of reading from or knowing aboout app.config from your Library assembly. The only configuration file that it knows or cares about is ConsoleApp.exe.config. Now it is possible to have configuration files reference each other but this is not the proper solution for what you are trying to do.
Since your Library assembly has no entry point, it will never be loaded into an AppDomain. Since it will never be loaded into an AppDomain its application configuration file will never be used.
What you ought to do is reference Library in ConsoleApp via a project reference. Then move all the relevant configuration data from app.config into ConsoleApp.exe.config as this is the configuration file that will be used by your application.
This will allow you to have to two things you need to invoke methods on your web service
The code in Library that can send and receive SOAP messages.
The configuration metadata that is required by Library to function.
An alternative to using a service reference in the class library and then copying the config would be to use build events that call svcutil.exe. The thing I like about this is that you don't have to make "update service reference" when the service changes. It will be updated automatically.
In the class library, use a build event that only generates the proxy code:
svcutil.exe net.tcp://localhost:3315/MyService/mex /noConfig
In the application, use a build event that generates the config. You can use the /mergeConfig option to merge it into an existing app.config.
svcutil.exe net.tcp://localhost:3315/MyService/mex
/config:App.config /mergeConfig
If you don't want to get a build error if the service is not running, put this in your project file and you will get a warning instead of an error:
<Target
Name="PreBuildEvent"
Condition="'$(PreBuildEvent)'!=''"
DependsOnTargets="$(PreBuildEventDependsOn)">
<Exec WorkingDirectory="$(OutDir)"
Command="$(PreBuildEvent)"
ContinueOnError="true" />
</Target>
You just need to copy the config key, pointing to the service, from your class library config file to your console app's config file.
You can copy the relevant portions of the app.config from the class library's configuration into the app.config for the console application.
Alternatively, if you're really trying to make this truly portable, you'll need to think about another way of referencing the address for the specific service reference from within the class library.
I'd think it more confusing if you had multiple configuration files running around.
If a library has configurable items, I would fully expect to have to put that configuration in my config file to properly consume the library.

Categories

Resources