Sharing classes between applications - c#

I'm working on a Visual Studio solution that currently has two projects in it (with more to come later). One project is a mature C#/Winforms application that I built last year (think of it as the prototype). The other one is a DLL that is going to do the same thing as the prototype but through a different application. I'd like to re-use code from the prototype (let's call the method in question SyncInvoices() ) in the DLL because the prototype code works perfectly b/c I've hammered the bugs out of it. The class that contains SyncInvoices is baked into the prototype application instead of being its own DLL.
I've added the class that contains SyncInvoices() to the DLL's project (as a linked file, since it already exists elsewhere in the solution). I can instantiate that class in the DLL project and call SyncInvoices() but the compiler throws errors related to GUI elements.
The problem is that SyncInvoices() has some-thread safe calls to the Prototype application's GUI in it, basically used to pass messages/errors back to the interface.
The DLL doesn't have a GUI, so it doesn't need to run that code. It still builds the rest of the methods in that class, even though they aren't used. Is there a way I can tell the compiler to ignore those lines when building the DLL? I'd rather not maintain two sets of nearly identical code, especially when the two projects are part of the same solution.
I thought about using #define/ #if blocks to partition off the code but I'm not sure if C# works that way-- most of the time I've seen those used is to keep debug code from ending up in production. If it is possible to tell the app to include/exclude code through #if blocks, how do I set the values?
Should I just bite the bullet and make a copy of the method without the offending code in it?

Without more specifics it's hard to give the correct answer, but I'd say generally you'd handle this with events. Whatever calls into the GUI are happening in the prototype, that would typically be some form of event, which you would subscribe to in the prototype when you instantiate your new class.
Are there any particularly problematic cases you could give more specifics on?

Related

Is there any way to auto run some code in DLL?

I have some DLL from third party that I need to license. It has some method that I must call from my own DLL. My DLL is referenced in couple of projects and I don't want to make changes to every hoster. Is there any method that I can use within my DLL which will call some method in my DLL? Like add some static class or constructor but without explicit call to that class from hosters? I am not sure if I am explaining it clearly. Please ask questions if needed.
ThirdPartyType license = new ThirdPartyType();
license.Load("license.xml");
This is a piece of licensing code that I want to place in my DLL and call it within the same DLL.
At the low level, the runtime supports "module initializers". However, C# does not provide any way of implementing them, so the closest you can manage is a static constructor ("type initializer") or just a regular constructor.
However, it is probably a bad idea to hook your licencing into either a module initializer or a type initializer, as you don't know when they will run, and it could impact code that wasn't going to access your lib. It is somewhat frowned upon to take someone's app down because your licensing code decided it was unhappy - especially if your library wasn't actively being invoked at the time.
As such: I suggest the most appropriate place to do this is in either a constructor, or a post-construction Initialize(...) method (with the tool refusing to work unless supplied with valid details).

Ensure only one class can access a reference dll?

I have a project where I want only one class to have access to a dll. I would be content with hiding the dll from intellisense, but still having access to it if that is an option. Either way, I want only one class to use the dll and for it not to be seen and/or accessible otherwise.
I'm using C# in visual studios.
Simply said: You can't do that (but keep reading).
Basically, a DLL (From the .NET perspective) is a bunch of code and config files. No more than that. So, given that you'll need to make public those classes in order to be used from another ones outside that assembly then you can not.
What you can do (I ended up doing this a few years ago) is to use some kind of reflection to determine which class (and namespace) is trying to access your assembly and only permit the proper one.
Other way is to implement a key negotiation between your DLL and the permitted assembly. You'll need to implement those manually, as far as I know.
Anyway, keep in mind there's always a way to bypass this kind of protection by disassembling and modifying your code. So, at least, don't forget to obfuscate the file. Anyway, this will just make it a little more painful, but still possible.
An alternate approach, if you goal is to stop people using the functionality of the dll by accident is to push your wrapper class into an intermediary assembly. Your project then references that intermediary project, rather than the underlying dll which effectively hides it. So your project structure would change to something like this:
Main Project -> references API Wrapper Project -> references API DLL
For this to work, your wrapper project needs to make sure that it doesn't accidentally expose any of the API DLL classes through its public interface.
Obviously this doesn't stop your developers from going in and adding a reference to the API DLL so that they can use the library directly, but if the goal is to stop accidental access to the API DLL classes because intellisense has helped the developer out a bit too much then it might be a viable option.

Compiling forms in C#

I want to compile each individual form on my application to be used sort of as a dll on its own... I looked into this and found very confusing representations of assemblies, which may or may not be what I wanted.
Is it possible to compile the form1.cs, form1.designer.cs and form1.resx to be 1 single file which then will be able to be used as a dll. I use "dll" as an example because that is the functionality I need with each of these forms when compiled to a single file, I need to be able to call it and use it from a shell application.
I know it is possible in VS to create a separate project which will compile into a dll but with something on the verge of 80 forms to compile... it will be a messy thing to maintain. So basically, is there an easier way?
this is the closest code I could get, but it is in console, so it will be impractical if there are easier ways... also I am not sure if it will actualy compile form1.cs, form1.designer.cs and form1.resx and still work as a dll
csc /target:library /out:MathLibrary.DLL Add.cs Mult.cs
Thanks for the help
Possible? Yes. Advisable? Umm, not sure.
You must study the CSC options to use it in such a massive way.
Partial classes are simply each listed among the sources. See here
The RESX file must be compiled by ResGen.exe to a resources file see here
You will use the /References parameter to include other DLLs.
The real challenge will probably come when you try to get cross references to work, depending on the layout of your application. Is there a main hub that will control all forms? Is it a plug-in architecture?
Good luck
Basically, you are working with solution. It can contain multiple projects. For each dll, you must have one project. So create 80 projects, add to each of them single form, edit it, add some logic.
Then there will be a main project, which produce exe. You can reference all dlls in that project, but better don't. If you do, updating any of dll will required recompiling that exe too. You can load them dynamically or use sort of plugin system (to enumerate dlls, understand their purpose, etc). Then you obtain Type from assembly (loaded dll), create instance (which will call constructor, which calls InitializeComponents, which loads form resources) and display form.
Regarding abstraction, you surely need something. To example, login window. You can create a generic form with some focus, user interface and user interaction logic. But it has to communicated with main project (which encapsulate encryption, password storage model, user rights, etc). One easy way to do this is to provide 2 interfaces:
interface ILoginImplementation
{
public void SetInitialUserName(string name);
}
interface ILoginLogic
{
public bool TryAuthenticate(string name, string password);
}
Implementation is what your form must implement and Logic is what main project implements and supply when instantiating login form.
I realize this is probably not ideal, but I still think your best bet is to use Visual Studio and create a separate project for each .dll to be created.
By right clicking the Solution node and selecting Add > New Solution Folder, you can at least organize your projects into a somewhat more orderly hierarchy. That alone might go a long way to make your project more manageable.
PS: If you haven't already, you should definitely try to create an interface, or a base class (or both!) that each of your Form-classes can derive from or implement. If you're able to abstract away and generalize some of the logic, it is quite likely to save you a lot of work down the road.

Result of "is" expression returns false when run, but true when inspected

I have the following code. The CustomControlHelper generates an instance of an object via reflection. At this stage we don't know what type of object we are dealing with. We do know it will be a CustomControl, but we don't know if it implements any particular interface or if it extends any other classes. The following code is trying to establish whether the loaded control implements the IRichAdminCustomControl interface.
Object obj = CustomControlHelper.GetControl(cc.Id, cc.ControlClass);
if(obj != null)
{
bool isWhatWeWant = (obj is IRichAdminCustomControl);
return isWhatWeWant;
}
That's all fine, but I've noticed that when I know I have an object that implements IRichAdminCustomControl, the expression evaluates to false.
Okay, this is where it gets really weird. If I inspect the code when debugging, the expression evaluates to true, but then if I immediately let the code run and inspect the result, it evaluates to false (I've attached an animated gif below to illustrate).
Has anyone come across weirdness like this before and if so, what on earth is causing it?
Incidentally, I believe the product I'm using uses Spring.NET to provide dependency injection in the CustomControlHelper.
If you are using Visual Studio 2010 SP1, I came across this bug:
Misreporting of variable values when debugging x64 code
There is a workaround on that page, posted by Microsoft:
You can either set all projects to compile to x86, or create an intermediate initialised variable declaration to ensure the debugger reports the correct value of the variable being examined.
Try this as a workaround:
bool isWhatWeWant = true;
isWhatWeWant &= (obj is IRichAdminCustomControl);
bool finalValue = isWhatWeWant; // this line should fix isWhatWeWant too in the debugger
return finalValue;
EDIT: seems like VS2012 also encounters similar problems in specific conditions.
Two possibilities come to mind. The first is that your interface name is generic enough that it could already be in the namespace somewhere. Try fully qualifying the interface in the is clause. The second possibility is that you might be running the code as part of a constructor, or being called indirectly by a constructor. Any reflection like stuff needs to be done after we are certain the application has fully loaded.
So I found the answer. It was because I had two copies of the dll in different locations. I had one copy in the bin of my back-end application and one in a shared external directory that gets dynamically loaded by the backend app.
I should explain; this application consists of two apps running in tandem, a frontend app and a backend app. Ordinarily, you place "Custom Controls" into your frontend app. These controls are then copied on application start to a external directory that is accessible to the backend app.
In this case, I had logic in my Custom Control library that needed to be accessed in the backend app - so I had to make a reference to it... which ended up with the backend app having two references to the same class. D'oh! And OF COURSE that's going to work when you're debugging.
Solution was to split my extra logic into its own project and reference THAT in the backend app.
I'm not going to "accept" my own answer here because, although it solved my specific problem, the solution is a bit TOO specific to the apps I'm working with and would be unlikely to help anyone else.
This happened to me once and even though I never came to a conclusion as to why it was happening I believed the PDB files that were being loaded with the debugging symbols where out of sync. So, by "cleaning" the solution and then rebuilding the solution this weird issue went away.

What are the drawbacks to duplicating a class in different namespaces?

I have a class called SimpleCommand. It is a single file class that implements ICommand in a very simple way (hence the name).
I am finding that I am putting it several of my projects. (I just copy the code and add it into the project.)
These projects are all in the same solution and resulting wpf application.
My question is: Aside from increasing the size of my DLLs by a bit, what are the drawbacks to copying this code around?
(I am trying to decide if it is worth the work to put it in a nuget package.)
NOTE: I have not changed this code in years, and I don't plan to.
The issue here isn't that there are various classes with the same name in different namespaces.
The issue is that you're duplicating code, which is really bad idea.
If you want to expand your SimpleCommand to ABitMoreComplexCommand you end up copying it all over.
If you need to compare one command to another by type you couldn't do that reliably - heuristics you may implement could give you false positives
Bottom line: make another project, put all reusable code there, don't copy it around
Copying and pasting is the most innefficient way of reusing code, IMO. What happens if you ever decide to add a simple bool property to this class? you will have to do it as many times as you ever copied and pasted it.
I suggest to group these reusable parts in a single DLL and reference them from multiple projects, instead.

Categories