How to make a DLL optional in a .Net app - dll

We have an app the requires Full Trust because of a Chilkat .NET 3.5 DLL
This has not been a huge issue, however we would like to submit our app to the: Windows Web Application Gallery and it must be Medium Trust.
So to make it medium trust all we need to do is
remove the reference to the DLL
comment out the methods that tie into that code
Rather than making 2 different versions of the app, what is the best approach to remove the reference to the DLL for one version of the app?
thanks!

That’s not a simple one, but my first thoughts on this would be to abstract it out with and interface and late bind it in, but you must remember to check you have full trust when you load it or it might not work.
static class Program
{
static void Main(string[] args)
{
Assembly asm = Assembly.Load("ExampleAssembly, Version=1.0.0.0, Culture=en, PublicKeyToken=a5d015c7d5a0b012");
IFullTrustAddin addin = asm.CreateInstance("Namespace.MyChilkatWrapper") as IFullTrustAddin;
if (addin == null)
return;
addin.DoSomething();
}
}
interface IFullTrustAddin
{
void DoSomething();
}

Related

How to configure AutoMapper 9.0 in IIS hosted WCF application

I want to use AutoMapper 9.0 in a WCF project containing several services that will be hosted in IIS. I've only found one other related SO question but its dealing with a 10 year old version of AutoMapper and is not asking the same question. Its answer is similar to the top hits on Google which suggest using a ServiceBehavior but that doesn't seem applicable when I want multiple services to use the same mapper. The defense rests.
In a web project, you might create a static MapperConfiguration in the Global.asax when the application starts, but WCF doesn't have a Global.asax. It looks like there are a few options for executing initialization code in WCF:
Include an AppInitialize() method in the App_Code folder. This will be dynamically compiled at runtime and people have complained that it can have missing reference issues in IIS so I'm not confident AutoMapper or its dependencies will be found once deployed to IIS.
Create a custom ServiceHost. This seems like it would execute once when the application starts, but also looks like it ignores the web.config configuration, which I don't want.
Use the Configure method per service. This has the same drawback as #2 and also I become concerned with thread safety (as in the ServiceBehavior approach) since two services could try to initialize the MapperConfiguration at once.
I considered just creating a class with a static property that would create a static MapperConfiguration or IMapper instance if it was not already created, but as in #3, I'm worried this may not be thread safe. Maybe if I did something like this?
public static class MapperConfig
{
private static IMapper _modelMapper;
private static readonly object _mapperLocker = new object();
public static IMapper ModelMapper
{
get
{
lock(_mapperLocker)
{
if (_modelMapper == null)
{
var config = new MapperConfiguration(cfg => cfg.AddProfile(new MappingProfile1()));
_modelMapper = config.CreateMapper();
}
}
return _modelMapper;
}
}
}
Where two services may call ModelMapper simultaneously. Another downside of this is the first request to any service will have to wait for the mapping to compile, but I'm not sure I can get away from that. I definitely don't want it compiling the mappings per call and would prefer not to even have to do it per service. Can you advise on the thread safety of MapperConfiguration and the best way to use it in IIS-hosted WCF?

How do I use Enterprise Library to specify config for only one DLL or subsystem?

How can I use EL to specify trace listeners and formatters for only one subsystem (say, DLL) of a large system?
I'm writing a sub-module of a very large large application (thick client, not web app) that uses a gateway/portal model to load its various subsystems. I'd like use EL 5.0 (already in use) to manage logging/tracing configuration, but just for my subsystem. It looks like app.config is getting converted by VS to foo.dll.config. Can I convince EL to pick up the settings in foo.dll.config (at run-time) and merge them into its existing configuration data, in memory? (Not into a merged config file.)
(Looks like, based on Enterprise Library Class Library App.Config, it can't be done.)
I wouldn't recommend trying to merge configuration -- it can can get messy.
Instead, I would configure your sub-module to configure and use private references to the appropriate Enterprise Library objects you need.
I'm assuming your module is a class library that has an app.config. When compiled it generates a module.dll.config file in the output directory. To take an example of logging using Enterprise Library 6, I would create a helper class to load your own configuration and maintain a reference to your module's LogWriter. In this way your module loads its own configuration and does not interfere and is not influenced by other configuration in the application.
namespace MyModule
{
public class MyModuleClass
{
public void DoSomething()
{
MyModuleLogger.LogWriter.Write("MyModule Test", "General");
}
}
public static class MyModuleLogger
{
private static Lazy<LogWriter> logWriter = new Lazy<LogWriter>(() =>
{
FileConfigurationSource configSource =
new FileConfigurationSource("MyModule.dll.config");
LogWriterFactory factory = new LogWriterFactory(configSource);
return factory.Create();
});
public static LogWriter LogWriter
{
get { return logWriter.Value; }
}
}
}
I've used a static class but you could use a variety of approaches that may fit with your design (singleton, factory, etc.)
You will have to ensure that your dll.config file is deployed along with your assembly. You could also hit problems if there are version issues with Enterprise Library (e.g. you are using Version 6 while the application uses Version 5.)

OO design - switching between modes

I am designing an application to monitor availability of components.
So first of all I'd have a Scheduler to run the availability checks (e.g. Jobs) in regular intervals.
There are a couple of components (and more are expected to be supported in future) to be monitored and for each of them there is a different way to find out if it's available or not.
So I was thinking I'd do an abstract ComponentStatusVerifier class with an abstract boolean method called verify and for each of the components I'd create a subclass to implement the specific verifying strategy.
The problem is a little bit more complicated though. The application is supposed to support running on two different platforms (e.g. servers, and there is a potential of supporting more platforms in future) and the set of components to be monitored depends on the platform where the application is deployed.
It is possible to either build the application separately for every destination server or let the application know where it's running through the configuration - so the problem is not how to make the application be aware of where it's running.
The question I have is how to complement the design of the application to support these run modes and at the same time to not lose the high cohesion of the individual classes.
You could have your ComponentStatusVerifier that checks one component also check whether it should verify at runtime based on where it's running. Your verify method should be extended a bit to support it: it should receive the relevant parameters: like the platform the application is in:
interface ComponentStatusVerifier {
boolean verify(VerificationParameters parameters);
}
interface VerificationParameters {
Platform getPlatform();
}
enum Platform {
PLATFORM1,
PLATFORM2 // ...
}
Also, from your description it seems that some diagnostic information would be important, instead of a simple boolean result. For that, I'd create a message list with information that the verifier can report on, something like this:
interface ComponentStatusVerifier {
VerificationResults verify(VerificationParameters parameters);
}
interface VerificationResults {
boolean succeeded();
Iterable<Message> getMessages();
}
interface Message {
string getDescription();
MessageType getType();
}
enum MessageType {
INFO,
WARNING,
ERROR
}
(Note that I've used interfaces and enums just to show the concepts, adapt as appropriate...)
A verifier that's running on a platform it doesn't support could do this:
class Platform1SomeComponentVerifier implements ComponentStatusVerifier {
#Override
public VerificationResults verify(VerificationParameters parameters) {
VerificationResults results = new ...
if (parameters.getPlatform() != Platform.PLATFORM1) {
results.addMessage(
new InfoMessage("Skipping verification of component, platform is not PLATFORM1"));
return results;
}
...
}
}
Ok, by your description it sounds like you should have a ComponentStatusVerifier.
That object should hold a ComponentConnectorClass.
The ComponentConnectorClass should hold a list of Verifier classes that will run and check all the things you need to verify.
Or you should be able to run the ComponentConnectorClass and then give it a list of Verifier classes to work with.
There are a few ways to tackle this problem.
You can configure all the applications to verify in your monitoring application. This is flexible and extensible up until a certain point.
Another way (although a lot more intrusive) is to have your applications to be checked register themselves in the monitoring application. This way the only thing your monitor has to do is call the applications that were registered. This is also very flexible and extensible since your monitoring application can be "dumb".
I would suggest using the proposed architecture of Yochai and have multiple Verifier classes each implementing another way of verifying, albeit a http request, rmi, etc.
You can write proxy class to do the coding necessary to check if it is alive.
// Remote box
class remoteObject {
int check() {
// I write code for this universe
// is multiverse true ?
}
}
class remoteObjectProxy {
remoteObject y;
int check() {
// do things necessary
return y.check();
}
}
// Your box
class localProxy {
remoteObjectProxy z;
int check() {
// do things necessary
return z.check();
}
}

Ambiguous reference in WCF and client application

I've managed to reproduce one of the errors in a test project with a similar structure to my production code. It consists of three simple projects:
Common (class library):
namespace Common
{
public enum PrimaryColor
{
Red,
Green,
Blue
};
}
Library (WCF service library), which has a reference to Common:
using Common;
namespace Library
{
[ServiceContract]
public interface ILibrary
{
[OperationContract]
PrimaryColor GetColor();
}
public class Library : ILibrary
{
public PrimaryColor GetColor()
{
return PrimaryColor.Red;
}
}
}
ClientApp (console application), which has a reference to Common, and a service reference to Library called "LibraryServiceReference":
using Common;
using ClientApp.LibraryServiceReference;
namespace ClientApp
{
class Program
{
static void Main(string[] args)
{
LibraryClient client = new LibraryClient("WSHttpBinding_ILibrary");
PrimaryColor color = client.GetColor();
}
}
}
The app.config files in ClientApp and Library are auto-generated and I have not modified them, and I have not changed the default configuration for the LibraryServiceReference in ClientApp.
When I compile this solution, I get the following errors in the ClientApp project:
Error 1
'PrimaryColor' is an ambiguous reference between 'Common.PrimaryColor' and 'ClientApp.LibraryServiceReference.PrimaryColor'
Error 2
Cannot implicitly convert type 'ClientApp.LibraryServiceReference.PrimaryColor' to 'Common.PrimaryColor'. An explicit conversion exists (are you missing a cast?)
please help me to fix this.
Make sure that 'Reuse types in all referenced assemblies' is selected in the Advanced options of Add service reference or Configure Service Reference.
it's because you're building x64 not "AnyCpu". I am running across this right now, and am trying to figure out if it's a bug, or if it's expected behavior.
Decorate your enum like this:
namespace Common
{
[DataContract]
public enum PrimaryColor
{
[EnumMember]
Red,
[EnumMember]
Green,
[EnumMember]
Blue
};
}
Update Your service reference (with checking reuse types just like Mark stated).
Rebuild your client code.
I have had this issue arise in innocuous, unpredictable manners so many times! I thought I'd share how I "fixed" it this last time.
I am using Visual Studio 2013 - but have had the issue down rev.
The ambiguous reference seems to come on by itself. I did nothing of note to cause it. In the latest instance I was debugging some code behind and suddenly I had 7, then 22 then 49 errors - all of the same nature.
I deleted the service reference altogether and re-added it. Simply modifying the re-use type did nothing. My solution has a WCF service, Class Library, UI and a Control Library. I also removed the using - in some code behind, of the class library.
This is an exceptionally troublesome issue which thankfully only occurs about every few weeks. Why this worked? Beyond my pay grade. I feel your pain! Hope this helps. In this case, the error came on, again, when I opened some code behind on a xaml page.
It sounds like you control both the client and the server code. Why do you want to create a service reference, is there a specific reason or is it just deemed easier?
In projects where you control both sides of the client server application you are better of creating a "contract assembly" (which is probably your common assembly). This contains the interfaces and objects that are involved with the contract and should be referenced by both your client and your server. In order to communicate with the service the client creates a proxy class using the ChannelFactory, there is no need to have a dedicated WCF client.
Example:
ChannelFactory<ISampleService> factory = new ChannelFactory<ISampleService>("Binding_from_config");
ISampleService sampleService = factory.CreateChannel();
sampleService.SomeCall();
factory.Close();
The factory pattern also makes it an ideal candidate for injecting your proxy in via IoC.
The benefits of referencing a common assembly over creating a service reference are:
No ambiguous reference as there will be no need for auto generated classes.
You will not have to update your service reference every time you change the contract.
For what it's worth, I was running in to this same error after moving my data contracts to a separate library. Updated the service references multiple times and tried all combinations of the settings for assembly reuse, to no avail.
What eventually fixed it for me was to 1) restart Visual Studio and 2) update the service reference. The auto-generated code in Reference.cs in the service definition looked very different and did not duplicate my data contract class. It used the proper reference from my library. So something must be getting cached in the IDE.
Hopefully someone else finds this useful.
I was able to fix this by right-clicking on the Service Reference and then changing from "Reuse types in all referenced assemblies" to "Reuse types in specified referenced assemblies" and then checking the specific common assembly.
Just remove the reference to Common project from your ClientApp project and the error should go away. When you're creating a proxy for your service, all dependent code from the service must be injected into the proxy. If you want your types to be same as those on the service side, just enable the 'Reuse types' option while generating the proxy code (otherwise they will be put under a different namespace).
The problem here is that PrimaryColor exists in both Common and ClientApp.LibraryServiceReference and you are referencing both namespaces in your class.
To overcome this issue, either explicitly reference the instance that you require, i.e.
Common.PrimaryColor color = ....
or set up an alias:
using Service = ClientLibraryServiceReference;
...
Service.PrimaryColor color = ......
When making the service reference aren't there some options that say something like: "inlcude common types in generated service contract" ?
I have the idea that in your service reference the classes are "copied" and that's why you get this error. Inspect the generated service files, remove then and add them again with "Add Service Reference" and see what options you have there.
EDIT
Although I'm almost sure that the Type PrimaryColor is defined twice. One time in the common project and one time in your service reference, you can also try this in your clientApp (to more explicitely specify the PrimaryColor Type):
Common.PrimaryColor color = client.GetColor();

Reference Windows Form Project From another Windows Form Project in same Solution

I have a solution with several projects most of which are code or control libraries. I have a main windows forms application that references and uses these libraries. What i am trying to do is create a 2nd windows application that extends the main one, but i would like to be able to deploy them as separate exe's.
When i try to add a reference to the new app referencing the main app; all seems fine until i try to run the new app i get several error msgs similar to below:
Error 1 Could not find file 'ADODB.dll' referenced by assembly 'D:\Visual Studio 2005\Projects\X\XX\bin\Debug\XXX.exe.manifest'. <newAppName>
i have tried adding references to all the dll's in the error messages and they are still listed when i try to run the new app. I thought of a few work arounds but they require user changes to maintain separate exe's at deployment. I would like to avoid this if possible. Any ideas?
Thanks in advance, Jeff
Your windows forms applications should not be the point that you extend, the exe files should really just be a shell for launching your process (as much as possible anyways). So this response doesn't answer your specific problem of reference exes as this is not considered good practice.
All the extensions should be made to your code or control libraries off a known interface or contract. Generally the process for extending applications like this is to use alternate or additional DLLs which are loaded at runtime.
Say you have an application called clock which is to display the time.
You can structure your application with a set of contracts (or interfaces) in a referenceable DLL "Clock.Contracts.dll":
public interface ITimeService
{
public string Name { get; }
public Date GetTime();
}
You then have each implementation of this in another DLL ("Clock.LocalComputer.dll", "Clock.InternetTime.dll"
public class LocalTime : ITimeService
{
public string Name
{ get { return "Local Time"; }}
public Date GetTime()
{ return Date.Now; }
}
In the UI/EXE you always reference the interface don't call the implementation.
How do you get an instance of the implementing class, using Reflection to identify if a class in a DLL implements the interface and Activator.CreateInstance to generate the class.
http://gsraj.tripod.com/dotnet/reflection.html
There are patterns like Inversion of Control and Dependency Injection which help to address these things in a standardized way in your application. 3rd party libraries like Castle Windsor, Spring can assist. A google search on these will give you some reading material.
I will say that it can take a while to fully get your head around these things.
ok i found a reasonable work around. Basically you add all the reused forms as existing items, but instead of just clicking add you click the drop down arrow and choose add as link.
It would be great to redesign as JTew suggested above but this gets me where i need to be without having to move code.
You can find more information here
Thanks for all your time looking this over and hopefully is helpful to more
Jeff Spo