Pass class object to different dll - c#

I have a little problem understanding what I should do.
I have a main project MainProj.
And another project called PluginHandler who has an IPlugin interface.
What I'm trying to achieve is to "send" an object called Network from MainProj to each plugin that implement the IPlugin interface.
My problem is what type should I write in the IPlugin, because it's in a different project I can't just say Network - and I can't reference it because I need a reference to the PluginHandler in the MainProj, in order to instantiate each plugin (using reflections)
Any ideas?

You need to create a "shared library". So instead of
MainProj
Network
PluginHandler
IPlugin
Plugin
you should have
MainProj
PluginHandler
IPlugin
Plugin
Common
Network
So you place the Network class inside the Common project and reference this by all other projects.

You just need to add the other project as a reference in your MainProj
and then add a using statement to import that namespace into your file.
When adding a reference you can either choose a dll or just choose another project.
How to add a reference
How to add a using statement

Related

Factory pattern where concrete classes are on separate DLLs

I wrote a dlls that connect to some 3rd party API, each DLL has the methods: SignIn,Upload,Download,SignOut.
My manager asked me to implement a factory pattern because in future I will write more dlls to other APIs that has the same methods signuture.
For now I have:
DLL 1: OneDrive
It has a class with methods: SignIn,Upload,Download,SignOut.
So if I want to use it I'm adding reference to this DLL and then any app can use this DLL.
DLL 2: DropBox
It has also class with methods: SignIn,Upload,Download,SignOut.
My question: How do I implement the factory method design pattern in this secnario?
What I did: I created another DLL("The new DLL") this DLL would contain the "FactoryClass", the problem is that the creator in this dll should return a type of "OneDrive" or "DropBox" that means I should add refernce to the first two dlls ("OneDrive" and "DropBox").
But, The classes "OneDrive" and "DropBox" should implement some abstrct class whithin the new dll that means I should add refernce to the new dll.
but it's not possible because it's circular dependency (Visual studio error)
In order to eliminate the circular dependencies, you must keep the dependencies in the direction of your main assembly.
This is in partly solved by an interface (or abstract class) declared in this central assembly, but there is the additional problem of instantiating the concrete implementations without directly referencing the dependencies.
This can be solved by allowing your factory to keep a registry of available implementations. You can find an example of a simple factory with registration in this other stack overflow question

MEF Container cannot compose parts from Shared Assembly

I have 3 projects in my solution:
1- ExporterLib (Class Library)
2- ImporterApp (WPF Application)
3- SharedLib (Class Library)
the first two projects reference "SharedLib" which contains an interface called ISharedClass .
Inside "ImporterApp" I have a class called ClassA:
public class ClassA
{
[Import] private ISharedClass part;
}
Inside "ExporterLib" I have a class called SharedClassExport:
[Export(ISharedClass)]
public class SharedClassExport : ISharedClass
{
//....
}
In ImporterApp I use a DirectoryCatalog referencing ExporterLib.dll file and a container. But when I try to compose the parts of ClassA instance using the container I receive an exception saying:
1) No exports were found that match the constraint:
ContractName SharedLib.ISharedClass
RequiredTypeIdentity SharedLib.ISharedClass
When I use the debugger to see the parts inside the catalog I see the correct SharedClassExport Part, but it's not referencing ISharedClass!
What Should I Do?
P.S. : I want to use MEF and I don't want to merge any of these projects together.
Thanks in advance.
SUMMARY:
//Specifying the contract type may be important if
you want to export a type other then the base type,
such as an interface.
https://msdn.microsoft.com/en-us/library/system.componentmodel.composition.importattribute(v=vs.110).aspx
Please try using [Export(typeof(ISharedClass))] . If you are exporting a type other than a base type, such as interface, it is important to specify the full contract type using typeof. To match the export use [Import(typeof(ISharedClass))]. Please let me know if this worked if not please provide the DirectoryCatalog composition logic you are using?
Check the bin folder of ImporterApp after your build. I'm willing to wager that ExporterLib.dll is not in the folder. Since ExporterLib.dll is not a direct dependency of ImporterApp MSBuild doesn't copy it to ImporterApp's bin folder on build. To fix this you have a few choices:
You can add a reference to ExporterLib in the ImporterApp project.
If you don't want to add the reference, a post build step on ImporterApp to copy the ExporterLib.dll to the bin directory of ImporterApp would also work.
You could also setup each project to build to the same directory in the solution structure.

Adding references for code moved into a class library

From a solution, which I made in Visual Studio 2013, I want to transfer a method to a DLL (class library project).
When I paste the method in the DLL project, it doesn't recognize parts of the code and it's showing this error`:
"are you missing a using directive or an assembly reference?"
Because of that, the DLL can't be built. I am assuming, that a certain reference to the solution is required, but I am not sure how to proceed.
I know how to add a reference from a solution to a DLL, but I'm not sure how it's done the other way around or even if it's possible.
You can't add reference to EXE from class library (assuming EXE uses that class library) as it will introduce circular reference.
Usually you need to refactor all dependencies so class library either have them all or allow application to inject dependencies from EXE/other clients. In later case class library needs to define base classes/interfaces to allow such injection.
Yes, you need to restore the same references that the original project uses, if they are used in the code you want to move.
If you need to do this by hand (i.e. without tools like ReSharper):
Move the code to the new assembly.
For each namespace or type giving the error, find it in the Object Browser.
Locate the assembly containing that namespace and type, and add a reference to that assembly in your new project.
You may also have to add a Project Reference to the original project.

How can I dynamically load classes from another project within Visual Studio 2012?

I'm developing a WCF service that uses an interface (not the ServiceContract interface) to perform some internal work. My goal is to extend the functionality of this service after deployment by delivering New DLLs with classes that implement this interface (and corresponding web.config updates).
I'm starting with just one class that implements the interface. In my solution, I have the Service in one project (WCF Service Application) with the interface definition, and the class that implements the interface in another project (Windows Class Library).
I am using the following code to dynamically load the class (based on a parameter passed when the service is called):
InterfaceFoo af = (InterfaceFoo)System.Activator.CreateInstance(AssemblyQualifiedName, ClassType).Unwrap();
When this line is called, I get a FileNotFoundException, Could not load file or assembly.
I believe the above code is correct, as I have it working at runtime from a separate proof of concept project once it's built and deployed, and the DLL is placed in the same folder as the EXE. I believe my problem is related to how I've referenced the projects, or the variables I'm passing to the CreateInstance() method when run within Visual Studio.
What I've tried and I still get the same error: In the WCF Service Project I've set the Class Library project as a reference. In the WCF Service Project I've added a link to the interface implementing class.
I'm wondering if the values I'm using for AssemblyQualifiedName and ClassType won't work within Visual Studio since they aren't yet deployed?
Any advice is appreciated, even if you think a completely different approach is better.
ADDED AFTER INITIAL POST:
I had an idea after posting, I moved the interface implementing class from the Class Library Project to the WCF Service Project. When I do this, it works. That to me eliminates the assembly and type parameters as issues, and the issue is that I'm not linking correctly to the Class Library Project.
You can move your interface defenition to another shared library (dll) and then use it.

Is it possible to have sub namespaces in the same dll?

I am creating a dll project. In this project I have a main namespace, for example myClasses. In this project, I create a new folder, myClasses2, so I have a second namespace, myClasses.myClasses2. When I create the dll, I get the myClasses.dll.
In other project, for example in a WPF project, I add a reference to this dll, and I can do "using myClasses" but I can't do "using myClasses.myClasses2" so I can't use this second group of classes.
There is any way to have, in one dll, the two namespaces? I would like to avoid to have two separate dlls, one for myClasses and other for myClasses2.
EDIT1: Thanks to all. The problem is that the classes are not public. I use the default when add a new class. When I set the class as public and generate again, I can using the second namespace.
Thanks.

Categories