I have a web application that refers to a DLL. This DLL has certain config values, which are normally part of the web.config.
There is a requirement to invoke this DLL under different configurations, from the web application. The DLL is third-party and cannot be changed.
Have tried the below and failed.
Have different copies of DLL (named a.dll, b.dll) and load it by reflection. The problem here is that it’ll still look for the web.config and not the a.dll.config. Also, since same Types are referenced in the main program as well as the reflected assembly, it goes crazy.
Change the config on the fly using AppDomain.CurrentDomain.SetData("WEB_CONFIG_FILE", #"Config\Path") and switch it back after the call. The problem here is that after the first time, it doesn’t load the config section again even if I switch.
Use ConfigurationManager.RefreshSection(#"configuration\mysection") to force a refresh. This doesn’t seem to work and people say this call is buggy in .NET
I've seen some recommendation to update the web.config, but this may not be a good choice for me because the switching of values would happen fairly frequently
Is there anything else I can do?
Host the DLL in a separate process and communicate using COM (or .Net remoting or a web service or similar).
I.e. create a host process a.exe using C# (say) which exposes classes as COM objects, the classes in turn calling the DLL methods/classes. Register as COM objects.
Then create b.exe the same (but with different CLSIDs).
You can now have different configuration files for a.exe and b.exe (in different folders), yet both can use the DLL services.
You could also do something similar by having two internal web apps and using SOAP or something to talk to them.
But the bottom line is if the DLL works on web.config, you have to put at least one of them into a separate process in a separate folder.
Related
Scenario
Consider having a solutions with 4 projects in it:
1) ProjectSql: This is a project, whose compilation output is set to Library, and this is responsible of accessing a SqlServer database and do something. The final library will be able to provide APIs in order to manage persistency for the final application.
2) ProjectWCF: This is a project, whose compilation output is set to Library, and this is responsible for defining service contracts, data contracts and service implementations to let my application host a service.
3) ProjectMiscellaneous: This is a project, whose compilation output is set to Library, and this is responsibe to provide APIs for other things.
4) ProjectApp: This is a project, whose compilation output is set to Executable (Exe), and this is responsible for creating the business logic of my application. Suppose this to be a simple Console application. This projects has references to all the other ones.
Assumption: Consider that every project has its own configuration file. ProjectSql, for example, defines connection strings to connect to a database and so on...
Problem: Configuration
Well, my problem is the following: consider that my application project ProjectApp uses ProjectSql, well, every call to a operation in ProjectSql needs to connect to database, in these calls the ProjectSql configuration file is referenced to get connection strings (a simple call to System.Configuration.ConfigurationManager....).
I think that if my ProjectApp, with its own configuration file, makes a call to an operation in ProjectSql, then, that operation will reference to its own configuration file.
My question is:
What I said, is it true???
Do configuration files respect the project hierarchy.
System.Configuration.ConfigurationManager can be told which config file to read. Any given app will normally have one config like appname.exe.config or web.config.
So the answer to you question is NO.
When you call System.Configuration.ConfigurationManager for any of the class libraries, it is the ProjectApp.exe.config file that is read.
I'm creating a Service for my organization that will be installed on hundreds of computers. The Implementation of it may need to change over time. After watching and read a bit about MEF I'm still a little lost. Is MEF a good soulution for say if I wanted to Drop a dll into the service folder and have that service pick up the changes?
I have done quite a bit with MEF. Yes, MEF will do what you're looking for, with a caveat...
You can discover and load in a new DLL at runtime
However, it loads into the same App domain as your main application so,
You can't unload or change the DLL without restarting your application
If that last point is a problem, consider MAF (although it's much heavier). But in MAF, it will load your extensions into a separate app domain.
Your other option is just to spawn off another process to handle the request, and pass command line parameters to it.
if you are using VS2010 i recommend you try first Click Once. It gives you the setup.exe but also gives you an HTML file (and other files), wich you can upload to an IIS server or an FTP site, or even to a shared folder over your local network. The thing is, when you configure your deployment you can tell the installer to auto-update all clientes directly from the site (the HTML file, ftp or lan shared folder). When user starts the application it will connect to the site and ask for an update if it exists, and if it does, the application will self-update. If you want to deploy an update, you only need to upload again the HTML file and all other files in the folder.
Check out this links:
http://msdn.microsoft.com/en-us/library/ms953320.aspx
http://weblogs.asp.net/shahar/archive/2008/01/29/how-to-use-clickonce-to-deploy-your-applications.aspx
Happy coding ;)
I am no expert about MEF. Documentation says Mef is all about making plug-in based systems. so your system expects some interfaces and MEF makes easy to import classes implemented these interfaces to your system.your case seems suitable for this. MEF has directory catalog and by using catalogs you can import types/dlls runtime.
How do I get a MEF Directory catalog looking at the same directory for both the Servicelayer and DAL?
I think you can do this if you have your service logic in a separated class library and you got the needed contract interfaces in another class library. Then you can create a directory catalog and import your service implementation with MEF (you only need to reference to the contract interfaces assembly). Then you can pick up the new dll/service implementation if changed. You only need a directory watcher (FileSystemWatcher), then you have to call your catalog's refresh method when directory watcher fires. In theory it should work, but it's just an idea. :) Anyway, hope this helps.
You could also look into Prism. From what I understand, they are two different frameworks to do pretty much the same thing. Prism allows you to create modules by having a class in a dll that implements the IModule interface. You can just drag and drop dlls into a folder this way just like in MEF. You can statically or dynamically load modules, and do a bunch of other things I don't even know about.
Prism also has other features bundled with it, i.e. the Unity dependency injection container (which I like to call "The Magical Black Box"), a neat event and command system, etc. I'm sure MEF has all these things too.
I have a solution that contains two projects. One project is a Windows Service that contains a few classes for performing various functions. The other project is a Windows Form Application that is meant for doing various testing and performing task that the service accomplishes on demand. For instance, the service will do a few various task at a certain time interval, but if you wanted to perform one of those task before the time interval has elapsed, you could load the Windows Forms Application and execute one of the task immediately. The Windows Form Application (from here referred to as the tester) references the Windows Service (from here referred to as Service) project. When the Tester loads, it creates an instance of one of the classes from the Service. Whenever buttons are pressed to perform the task, it references that instance that was created and calls the various methods of the class. The Service has uses application settings for the configuration, and thus has an app.config. The configuration settings are accessed using [ProjectName].Properties.Settings.Default.[SettingName]. When the configuration settings for the tester are changed on its own app.config (or exe.config after release), the settings are refreshed without a problem. If the tester is closed, configuration is modified, and then reopened, the new settings will be populated. If the Reload method is called on the Settings, the configuration is refreshed without a problem. The Service performs in the same way. The configuration settings are can be updated without a problem.
The problem is that if configuration changes need to be made on the service, when the service methods are called from the tester, the configuration does not take the new settings. Whatever settings the project was built with will be used. I cannot get the tester to recognize that the app.config/exe.config for the service has changed, and the new configuration should be reloaded and used instead of whatever configuration was used when the project was built in visual studio. Perhaps it I am not educated enough about this topic, but it seems to me that the app.config is rolled up into the .exe file created by the Service whenever it is built.
I have tried encapsulating the Reload method for the Service and calling it, and it doesn't seem to make a difference.
I have an example project that performs as is described above on a very basic level. The ideal goal is to be able to modify the exe.config file or files on the fly and have both the Service and the Tester pick them up without any problems. If you would like to see exactly what I mean from a coding perspective, an example project can be found here: example solution
Any help would be greatly appreciated. Thanks you for your time.
Update
I have managed to find A solution to this, but I am still curious if there is a better way. By using an app.config that is shared between both projects and using the Configuration Manager instead of App Settings, everything works as it is expected to. I prefer to use App Settings if at all possible; however it will work to use a shared app.config and the Configuration Manager pointed at that app.config.
One option is having both programs load from the same configuration file:
http://msdn.microsoft.com/en-us/library/system.configuration.configurationmanager.openexeconfiguration.aspx
Found the solution. An app.config must be added to the solution as is described above in my update. Once linked like that, you can add a settings file to the project and add settings/configuration to the project and they will be added to the solutions settings file. This will move with the build and fix the problem I was having.
I have a web application that dynamically loads assemblies based on database configuration entries to perform certain actions (dynamic plugin style architecture).
The calls to the objects are in a Factory Pattern implementation, and the object is cached (in a static dictionary<> within the Factory) as the calls can be made many thousands of times in a minute.
The calls to this factory are made from both the main web application and a number of webservices, some in different assemblies/projects.
When I need to update one of these DLLs, I have to recycle IIS to get the DLL released.
As this has an impact on another application on the server, I wanted to know if there was a way I could release the DLL without restarting IIS?
There's absolutely no way to unload a loaded assembly other than killing the AppDomain which is basically what you are doing when you restart IIS.
You can try restarting the application pool not the whole IIS server. Maybe that will do the trick for you
If you have an assembly that you need to load and unload you will have to jump through a few hoops.
the types being loaded must derive from MarshalByRefObject
the types being loaded must derive from an interface that will be used to call them
you must build a remoting based 'loader' to isolate the loaded assembly in a new appdomain, which can be unloaded.
see http://www.west-wind.com/presentations/dynamicCode/DynamicCode.htm for a good introduction. It is a bit dated and deals with dynamically generated code but given your rep I would assume that you can extract the relevant information.
I need to create a project for multiple web services using WCF in c#. The web services will be calling other assemblies to perform the core processing. The assemblies will be accessing data from SQL Server. One of the parameters that will be part of every web service method will include the database to use. My problem is how to pass the database parameter to assemblies to use. I can't change all the signatures for all the satellite assemblies to use. I want to reference some kind of variable that the satellite assembles reference. Theses same satellite assemblies are used with a Windows Forms app and an ASP.NET app so I would need to have something that all types of applications could use. Static fields are not good since for one web service call the database could be "X" and for another it would be "Y". Any ideas?
This is the sort of thing that might play nicely with an IoC or DI framework - having some interface that includes the database information, and have it pushed into all the callers for you. Even without IoC, hiding the implementation in an interface sounds like a solid plan.
With your static concept; a [ThreadStatic] might work but is a little hacky (and you need to be religious about cleaning the data between callers), or another option is to squirrel some information away on the Principal, as this is relatively easily configured from both WCF (per-call) and winforms (typically per-process). In either case, be careful about any thread-switching (async, etc). In particular, note that ASP.NET can change threads in the middle of a single page pipeline.