I built a fairly complex system of libraries, I would like another programmer to load one of my assemblies read its properties, call its functions and listen to its events. At the moment the end programmer would have to reference Library1 and put together with it the rest of the libraries that Library1 depends on.
To get rid of this issue I would like to make an installer that copies all the libraries to a location and the end programmer will reference just a MainLibrary that dynamically loads the rest of the libraries and exposes what needs to be used.
Assembly library1Assembly = Assembly.LoadFrom("/path/to/where/the/libraries/where/installed/library1.dll");
Type? library1Type = library1Assembly.GetType("Library1.MainClass");
dynamic library1Instance = Activator.CreateInstance(library1Type);
Library1 has some public classes I would like the programmer to access to though, like User
for example. MainLibrary exposes two properties List<User> Users
and User SelectedUser
that Library1 already has, so I would need to create a MainLibrary.User
class that is a complete copy of the Library1.User
class and the same needs to happen for several other classes, custom EventArgs and so on.
I don't really like this duplication, is there any other way to achieve the same result?
The approach I'm familiar with is to create a third library, say "Interfaces", that contain common class definitions, interfaces, and other types. This should be shared between both projects.
You can then use reflection to resolve the type that implements some root interface, and create an object of that type. From that point you can use the root object to create any other types, or do other things.
The Create a .NET Core application with plugins article seem to demonstrate this approach.
If it possible to version this interface, to allow some version mismatch between the main application and the library. But you need to add explicit checks to avoid using any unimplemented method/property/type.