I have an interface called IProjectUser that defines a read function and a write function for reading and writing to project files. I also have a class called Project that holds a generic list of IProjectUser objects to manage project files. Both of these are in the class library Project.dll.
I also have a class library called A.dll that contains a class called Foo which implements IProjectUser. The ability to read/write project files is secondary to this class. It holds and manipulates some data. A.dll references Project.dll.
The application also contains some forms and other classes that implement IProjectUser.
I can imagine a situation in the future where I might want to use A.dll in another project that doesn't use project files. However I will be forced to include Project.dll just because A.dll requires it. Even though the functionality is optional.
Is there a different design pattern that would allow me to essentially make an interface optional?
I hope I explained this clearly enough.
Update
What about casting objects to interfaces? This would open up the possibility that an interface is not implemented correctly. Is that a good or bad design approach for this kind of problem?
if (Foo is IProjectUser) {
ProjectUsers.Add(Foo as IProjectUser);
// etc
}
Use inherited or multiple interfaces. You cannot make an interface method optional.
Casting your object to an interface that it doesn't implement will not work -- you'll end up with a null value in your variable. What's wrong with using proper design and adding B.dll as suggested below? A.dll becomes completely reusable, and you still get to have a version of Foo that implements IProjectUser.
Drop the reference to Project.dll from A.dll.
Drop IProjectUser from Foo.
Create B.dll which references Project.dll and A.dll.
Create FooProjectUser in B.dll which inherits from Foo and implements IProjectUser.
Move the project specific logic from Foo into FooProjectUser.
Use FooProjectUser in the places where you currently use Foo, freeing A.dll from any references to Project.dll.
Related
Ok, this may be an easy question but its been so long since I've done it.
I have a library (libA) that contains classes. I want to create a new library (libB) that inherits and extends a class from libA:
public class c1:libA.c1(){}
One of the methods in libA.c1 returns another class defined in libA:
public c2 m1(){}
When all done, I want to utilize libB without any references defined to libA in the future code. However, I cannot seem to be able to do it because I have to have a definition of c2 somewhere and simply inheriting:
public c2:libAc2(){}
doesn't seem to do it.
Can anyone give me any pointers on how to expose c2 through libB and "hide" libA to any programs that reference libB?
If you have a chain of reference like this...
Application - libB - libA
Then you will need to include a reference to libA, otherwise it will simply not build your application. libA is a dependency of libB, after all. You're going to need it to run your application.
You can do some fancy loading of classes at runtime, loading assemblies manually, but this won't allow you to write code based on them, as such. So, it won't be of much use to you here. https://msdn.microsoft.com/en-us/library/system.reflection.assembly.loadfile%28v=vs.110%29.aspx
My best advice would be to refactor the code from libA into libB, provided you have the source code for libA. Then mark the classes you wish to hide from outside the assembly as internal.
https://msdn.microsoft.com/en-us/library/7c5ka91b.aspx
For example, I have a large class library that does a number of things... I build it into a project. Some of the class objects depend on "Copyrighted.dll" - but this project is not going to use any of the class objects with "using Copyrighted"... Will the DLL still be functional for classes that don't depend on that?
I suppose I could try to test this out somehow, but I'm not in a place with the code that it's easy at this moment.
I have an assembly that contains base objects for my Business Objects, and then another assembly that is automatically generated and populated with classes based off a database schema. The classes in the latter assembly all inherit from a class in the former.
The idea I had was that I could reference the generated assembly from other projects, and 'not' the assembly with the base objects thus hiding some of the implementation details and prohibiting people from using these objects.
Unfortunately, I am realizing that I cannot use any of the functionality built into the base unless I reference it as well. So my question is: Is there anyway around this, and if not then is there a design pattern that addresses this that I should be using?
Question sounds slightly backwards. You are hiding your business/domain layer with your data layer? Generally that would be the other way around.
Either way. The issue sounds like you have:
Assembly A
class Bar
Assembly B
class Foo : Bar
Assembly C must reference both A and B to use Foo.
The design principle to follow would be to favor composition over inheritance.
Rather than Foo inheriting from Bar, Foo could contain an instance of Bar and expose what methods make sense for Foo. This is all assuming that Foo is not actually a specialized version of Bar.
If you really don't want to expose the base classes to others (think extensibility), then you probably should move the bases into the same assembly as the concretes.
If you still need the assemblies separated, you can still make the bases internal, and then set the InternalVisiblesToAttribute on the base class assembly:
(In AssemblyInfo.cs)
using System.Runtime.CompilerServices;
[assembly:InternalsVisibleTo("ConcreteClassAssembly")]
This strikes me as likely to have an agreed best-practice answer, but I can't seem to find one anywhere.
I have an application that will load and use classes that implement a specific interface. The implementation classes will be written by someone else and I want to send them the minimum they need to successfully implement the interface.
So far the best I've come up with is the following:
The application solution that contains:
A project that contains just the interface definition and compiles to a dll.
A project for the application that uses the interface and references the dll.
A separate solution for an example implementation that builds to a dll and references the interface dll.
Is this the best way to do this? i.e. distribute a compiled version of the interface to anyone that needs to implement the interface.
I tried using just a copy of the interface source files in the example implementation and my application failed to recognise the class as implementing the interface. Is this to be expected or is my class loading code bugged (it does work when the example references the pre-compiled dll)?
you should put your interface in an assembly and then distribute your assembly (or your whole project if needed) so that the other people who want to implement the interface just need to reference your assembly so they have access to the same interface (which is not the case if you just send the interface (.cs) file as your interface will be embedded in another assembly and thus will certainly have another namespace or assembly name and thats why your implementation class was not recognized as inheriting your interface cause basically it was not the same interface even if the methods and properties where the same ;))
i think your approach first is the best if you dont want people to change your code and just use the interface
otherwise just share the whole project containing the interface
That's the approach I've used, and seen in other projects - give the shared assembly a generic name such as MyApp.Interfaces, in case you end up with multiple shared interfaces.
An alternative approach is to use the Managed Extensibility Framework: http://msdn.microsoft.com/en-us/library/dd460648.aspx - but that may be overkill for a small project.
I currently have a C# project which uses plugins and has a fairly common approach to plugin handling: an IPlugin interface is stored in a dll which is linked in a tranditional dynamic way. The host app looks for class libraries exporting classes exposing this interface and loads them via reflection at run time.
The dll containing the interface also contains helper classes, for updating plugins, providing abstract base classes and so on.
My question is, what does it take to break the interface between my host and plugin assemblies? In other words, if I compile and distribute the host app and then distribute plugins that have been linked with a later version of the plugin dll (in which helper classes have changed, but IPlugin is defined in exactly the same way), will the host still pick up the plugins? How much of a change do I need to make to the plugin library before IPlugin is considered a different "type" by the reflection methods I am using?
If the assembly isn't loaded by a specific version than I would say the only breaking changes you will really encounter are when you change the interface contract. If you are just changing helper classes it shouldn't be a problem.