What is the proper way to link classes in separate projects? - c#

I have a Solution which consists of two projects - the Manager and Viewer. Naturally, both use the same classes, e.g. Manager is used to edit data in SomeItem class instances, while Viewer is used to display it's data.
I have all class definitions in the Manager project. To use them in the Viewer project, I created the same directory hierarchy in the Viewer and linked all classes with build action set to "Compile".
But now I'm getting tons of warnings like this:
The type 'SomeItem' in 'Manager\Classes\SomeItem.class.cs' conflicts
with the imported type 'SomeItem' in 'Viewer, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null'. Using the type defined in
'Manager\Classes\SomeItem.class.cs'.
What is the best way to use the same class in two projects while having it in a single file?

I would suggest that you create a separate project with the classes you want to have in common, set application type as Class library, after doing this and compiling it you will be able to add it as a reference to both of your other projects by right clicking on references and adding it as a project reference.

Related

Converting a C# class I created inside a project to a separate reusable class

I'm not new to C# programming, but I suppose I'm new to programing "the right way" in C#. I've worked in C on embedded devices for years and have written desktop apps to support them. First in VB6, then in C#.
I recently started making better use of classes for reusing code (and for instantiating more than one instance of the class in a program). For example, I "wrapped" a UART interface with some additional functionality so I can use the same code for multiple ports by creating an instance of the class for each one.
It is in a separate file, but still in the same program namespace, so when I want to reuse it, I have to copy the file and change the namespace to the new project.
I'm sure there's a way to create it such that I can just reference it like everything else with either a "using..." reference at the top of the program or with a "Project | References..." checkbox. But for the life of me I can't find a good learning journey for this.
Any direction would help.
You want to create your reuseable class in an assembly - this is the equivalent of a dll from your C experience.
To create an assembly, have a separate project of type assembly (instead of exe) . You can reference the assembly from other projects. If your project is in the same solution you can reference the project, otherwise you can reference the compiled assembly.
C# uses a packaging system called Nuget, so you can package your assemblies into "Nugets" which you host in a Nuget Server. You can then use tooling to discover and import these.
Please create a Class Library project and include your class into that project. Make sure your class is public. Once you build this project you'll get an assembly which can be referenced from other projects. See Tutorial: Create a .NET class library using Visual Studio
There are different ways of referencing it.
You can have the class library project in the same solution as the main project. In this case you should add a project reference.
You can copy the compiled *.dll file to some folder in your solution (e.g. Lib) and add an assembly reference.
If this assembly is to be used in multiple projects please consider creating a NuGet package with this library and pushing it to some repository. Then other projects can add a package reference to this package.
Details:
How to: Add or remove references by using the Reference Manager
Install and manage packages in Visual Studio using the NuGet Package Manager
It is in a separate file, but still in the same program namespace, so when I want to reuse it, I have to copy the file and change the namespace to the new project.
Well, it isn't the best practice but (unfortunatly) still a common behavior. So don't worry to much about it.
What you could do to improve it place the file (and other reusable parts) in a seperated csproj.
For example name the project of the type class library and name it VinDag.Tools. Within the project create a folder UART and place the wrapper there. The namespace of the wrapper would then be VinDag.Tools.UART.
From know on you can just reference the class library instead of renaming the file. It's not necessarily required to be the same namespace as the project.
From there you can start considering (private) nugets. This would prevent you from copying files/csproj around.

How can I deal with this MEF related ReflectionTypeLoadException exception?

I have three projects, v.i.z. Shell.Core, Shell, and Services.Employees. Shell imports parts from Services.Employees, i.e. the latter project is external and not referenced in any of the solution projects. As well as Shell, `Shell.Core' is also a WPF application, not a class library. I started it as that project type for DevExpress to include all the correct references for me, as it defines certain shared UI components.
Services.Employees does reference Core, which defines certain base classes it uses. Now, when the startup application, Shell, it should load Core, and then it does MEF composition, loading Services.Employees parts from a DirectoryCatalog, but MEF sees the dependencies on Core and wants to load them from that catalogue, although the host application already references these Core dependencies.
As example, when I try composition, I get an error like:
Exception: 'TypeLoadException': Could not load type
'Shell.Core.MappedViewModel`1' from assembly 'XTime900.Shell.Core,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
What are my ways out of this? Should I also import Shell.Core.MappedViewModel, although it is already in a referenced project? Should I convert Core to a class library, so it will appear in the catalogue directory as a DLL and MEF will load it as a dependency of Services.Employees? Is there any other way to get around this sticky little problem?
It looks like this happened. Shell.Core.MappedViewModel1, referenced by the plugins, loaded the ViewModel types. Then, the MEF plugins referenced this project, and during composition, couldn't find the right objects. When I factored View Models out into a separate project, referenced by bothCore` and the MEF imports, all worked well again.

Unable to create object

There is a .Cs file in one of the projects in my application and i want to create an object of the class(in some other project inside the application) that is inside the .cs file, i tried to add the reference of that particular project but it is giving Circular Dependancy error and i am unable to create the object.
Break out common code to a third assembly and reference that one in the other two projects.
You get a circular dependency becuase the project in which the object reside already references the project that you want to use the object in. This is probably a design problem as well.
One solution is to create a new project (Common) that both projects can reference.

Read resources from a DLL file

I've two Visual Basic 2008 projects - one is a class library project and another is a Windows Forms project. In the class library project, I've defined some strings in the project resources (project properties > Resources tab).
I build that class library project and get the DLL file from the debug folder and added up as a reference in my Windows Forms project.
How do I read those strings from the referenced DLL file?
While you can dynamically load the DLL as ho suggests, it's fine to use a reference as you have done. In fact I would recommend using a reference unless you had a particular requirement to dynamically load the resource assembly.
As to accessing the resources there are a few things you need to do.
In the resource assembly you will need to ensure the resources are public. By default resources are set to internal which means you will not see the resources in the winforms app. Double click on Properties\Resources.resx to open the resources view. In the top toolbar you will see a label "Access Modifier" next to a combo box drop down. Change the selection to public.
You will need to reference the assembly from the forms app. You have stated you have already done this. Just a note that a better way to do this is to create a solution that contains both projects. Then in the forms app choose add reference. Click on the Projects tab up the top. Double click on the resource DLL project name. This works better than referencing the debug DLL directly since it means if you change between a release build and debug build in your forms app, it will automatically build a matching release/debug version of your resource assembly.
Once you have added the reference you can simply reference the type out of the resources DLL, e.g.
ResourceDLLNamespace.Properties.Resource.ResourceName
Just a note, you need to be aware of type name clashes if you are using the same namespace for your forms app and resource DLL. In this situation both your forms app will have access to it's own Properties.Resources class as well as that of the resource DLL. You can do two things to avoid this:
Use a different namespace between the two assemblies
In the resource assembly don't include a default Properties\Resources.resx resource dictionary. Delete it and manually add a new resource, i.e. Add New Item and select "Resources File". You should find that you will not be able to add the new resource dictionary to the Properties folder - add it to the root or some other folder as you require. This will automatically give it a different type name by virtue of being in a different folder. You still may want to avoid using the resource file name of "Resources" however, as if you have all the relevant namespaces in scope via using statements you will get the same issue that the compiler won't know which version of Resources to use.
-Donovan
I think you just use System.Reflection.Assembly.Load to load the other assembly then use the constructor of System.Resources.ResourceManager that takes an assembly.
Note, I don't think it needs to a reference for this to work.

VS 2008 C# : Class library is not accessible in another class library in same solution

I have a solution in VS 2008 which has one web project and 3 Class libraries as 3 different Projects. One project is for DataAccess and one is for BusinessLogic.
I have a class in DataAccessLayer. From there when I am trying to access the Class of BusinessLogic class library (project) it is not coming in the IntelliSense when I type. I used the same namespace in both projects. Still same results.
Do I need to to create DLLs for the first project and add as reference to second?
You need to add reference to this project in another project in your soultion.
Visual studio has an option to add project as a reference, so you don't have to add assembly files directly
You need to reference the library in the other projects.
To do that, right-click the references folder in the Solution Explorer, click Add Reference, go to the Projects tab, and select the library that you want to reference.
EDIT: Also, make sure that the class you are trying to use is declared as public (eg, public class MyClass).
If you leave out the public modifier (which is the default), the class will only be usable in its project. To expose classes and members to other projects, add the public modifier to their declaration
You'll need to add a reference to the project containing the BusinessLogic class in the DataAccess project. Otherwise, the compiler doesn't have anyway of finding the implementation of your BusinessLogic class, even if it does use the same namespace.
This may sound silly, but have you specified the class in question as Public or Friend? They'll need to be "shared" in that sense in order to be properly picked up and used within the other applications, even when the project reference is specified.

Categories

Resources