In C#, I have a class hierarchy with a couple of abstract base classes near the top and a fair number of derived classes. A few these concrete classes have some common properties and methods that are implemented identically. It strikes me as wasteful and so one solution might be to implement this common behaviour in another abstract base class.
abstract class Control;
abstract class SquareControl: Control
{
public int SquarishProperty;
public void SquarishMethod();
};
class Window: SquareControl;
class Button: SquareControl;
However, what if several other classes in the hierarchy shared some other behaviour but also share something in common with one of the controls from another base class? Perhaps there are lots of areas of commonality. It would become impractical to model this with abstract base class implementation wouldn't it?
abstract class FlashableControl: Control
{
public int FlashyProperty;
public void FlashMethod();
};
class StatusBar: FlashableControl; // but it's also a bit square too, hmm...
So how do you go about sharing such implementations across classes without using base classes?
I imagine I want to delegate the implementaion of an interface to another class and have that class implement those properties and methods on behalf of the desired classes, so that to the user, the StatusBar and Window appear to support a standard interface, but under the covers it's something else that implements it.
I can visualise aggregating classes that implement this behaviour, but is this appropriate and are there any pitfalls? What are the alternatives?
Thanks
You can use a pattern like this:
public interface ICommonServices
{
string SomeProperty { get; set; }
void SomeMethod(string param);
}
public static class CommonServiceMethods
{
public static void DoSomething(this ICommonServices services, string param)
{
services.SomeMethod(services.SomeProperty + ": " + param + " something extra!");
}
}
All classes that implement ICommonServices now also get some free behavior via the extension method, which depends solely on those features exposed by all ICommonServices implementers. If you need access to base class functionality, you can put that in its own interface and have ICommonServices implement that interface as well. Now you can create 'default' extension functionality for interfaces without having to use multiple base classes.
EDIT
If you want some of these methods to be internal, you can modify the pattern like this:
public class MyObject : IServices
{
public string PublicProperty { get; private set; }
string IServices.SomeProperty { get; set; }
void IServices.SomeMethod(string param)
{
//Do something...
}
}
public interface IPublicServices
{
string PublicProperty { get; }
}
internal interface IServices : IPublicServices
{
string SomeProperty { get; set; }
void SomeMethod(string param);
}
internal static class ServiceMethods
{
public static void DoSomething(this IServices services, string param)
{
services.SomeMethod(services.SomeProperty + ": " + param + " something extra!");
}
}
Basically we're exposing both public and internal interfaces. Note that we implement the internal interface methods explicitly, so that the methods are not available for public consumption (since the public client can't get access to the interface type.) In this case, the helper extension methods are internal, relying on the internal interface, though you could also create public helper methods that rely on the public interface.
You could use 'has-a' instead of 'is-a' and delegate to an internal square control
class Window : Control, ISquareControl
{
private SquareControl square;
public void SquareOperation()
{
square.SquareOperation();
}
}
class SquareControl : Control, ISquareControl
{
public void SquareOperation()
{
// ...
}
}
One way is to use Interfaces and Base Classes.
Flashable would make a good Interface instead of a class.
Related
I'm using a dll with a lot of classes. I'd like to implement dinamically interfaces for these classes, then I can unit test them by mock.
Is there a way of doing it?
Example:
The dll has a class Comunicator
public class Comunicator
{
public void Execute()
{
//execute something
}
}
Is there a way of doing this class implementing the interface below dinamically?
public interface IComunicator
{
void Execute();
}
This way I want that the property below
public IComunicator Comunicator{ get; set; }
Be able to understand this assignment
Comunicator = new Comunicator();
Is there a way of doing this class implementing the interface below dynamically?
Short Answer: NO
If the dll is a 3rd party library then there is nothing you can do to modify that class as you have no control over it.
You could however create your own classes and abstraction to encapsulate the 3rd party dependency.
You create your desired interface
public interface IComunicator {
void Execute();
}
And either using encapsulation
public class MyCommunicator : ICommunicator {
private readonly Communicator communicator = new communicator();
public void Execute() {
communicator.Execute();
}
}
or inheritance (if the class is not sealed)
public class MyCommunicator : Communicator, ICommunicator {
}
This way the property below
public IComunicator Comunicator{ get; set; }
Will be able to understand this assignment
obj.Comunicator = new MyComunicator();
In case I want any class inherits/implements some methods which is better an interface or an abstract class contains these abstract methods only and acts as an interface. I know the difference between the interface and the abstract class well but in this case do the two have the same function or there are different something?
I think we can feel free to use one of them but still I take the side of interface because my aim is to enforce any class to implement these methods and it is the job of interface.
I agree an abstract class with no concrete behavior seems a little pointless so I would favour an interface.
Abstract classes are far more useful when bringing together some common behavior that cannot be overridden along with some elements that can eg) template methods
public abstract class Base
{
public void TemplateMethod()
{
AbstractMethod1();
AbstractMethod2();
}
public abstract void AbstractMethod1();
public abstract void AbstractMethod2();
}
public class Concrete : Base
{
public override void AbstractMethod1()
{
Console.Write("Override Abstract Method 1");
}
public override void AbstractMethod2()
{
Console.Write("Override Abstract Method 2");
}
}
public class Main
{
public Main()
{
var concrete = new Concrete();
concrete.TemplateMethod();
}
}
This question might be a bit odd. The scenario is as follows:
There is an interface for plugins called IPlugin
There is an abstract base class for plugins (which implements the interface) called PluginBase
These are stored inside a class library
Now everyone should be able to create their own plugins by creating a new class library and a plugin class which derives from PluginBase.
The PluginBase class will provide many public properties which are used from the base tool to communicate with the plugin interface. This is done by reflection; the tool searches for a class which is based on the interface IPlugin and creates an instance of that class.
Now the problem is that these public properties are necessary for the plugin mechanism but should not be accessed or changed from the derived plugin class. In short: the user-defined plugin class should not be able to access several public members of its base class PluginBase.
Is this possible somehow? I know that I normally should use private for those properties (so the derived class can't access them) but as the base class also acts as a plugin interface, this is not possible.
Solution (based on answers of Fabjan and Luaan):
// basic plugin interface (IPlugin.dll)
public interface IPlugin
{
// plugin communication interface
string SomeProperty { get; set; }
void SomeMethod();
// public interface
string Name { get; }
void Run();
}
// plugin base class (IPlugin.dll)
public class PluginBase : IPlugin
{
string IPlugin.SomeProperty
{
get { return "Something"; }
set { /* ... */ }
}
void IPlugin.SomeMethod()
{
Console.WriteLine("Something");
}
public string Name
{
get { return "MyName"; }
}
public void Run()
{
// ...
}
}
// user-defined plugin (MyPlugin.dll)
public class MyPlugin : PluginBase
{
public MyPlugin()
{
// will not work
this.SomeProperty ...
}
}
// main assembly
static void Main(string[] args)
{
Assembly asm = Assembly.LoadFrom(#"path\to\assembly");
var type = asm.GetTypes().FirstOrDefault(t => t.GetInterface("NamespaceOfIPlugin.IPlugin", true) != null);
NamespaceOfIPlugin.IPlugin plugin = (NamespaceOfIPlugin.IPlugin)Activator.CreateInstance(type);
// works as expected
plugin.SomeMethod();
}
If you don't want the properties to be public, don't make them public.
The architecture of your solution seems to be wonky at best. You expect (require even) all plugins to implement PluginBase, yet you search for plugins based on the IPlugin interface. Why? Pick one, and roll with it. There's no rule in the framework that plugins must be searched for based on some interface.
To prevent a derived class from accessing the members of its parents, you use the private access modifier. If your plugin manager needs to have access to those values, you must make sure it actually does - for example, you could make the part responsible for working with this data a sealed nested class of PluginBase.
But in the end, the question is - why? There's little point in trying to force the derived classes to avoid accessing those members (why have those members in the first place?). Perhaps it would be enough to have those properties in an interface that would be implemented explicitly? That way you could still use e.g. ((IPluginBase)plugin).SomeProperty, but not plugin.SomeProperty. It's not like they couldn't get to the data using reflection anyway.
Now the problem is that these public properties are necessary for the
plugin mechanism but should not be accessed or changed from the
derived plugin class.
What you try to do isn't really possible because if class implements abstract class - it must know all its members. What you can do is you can do something like this:
1) Add internal keyword for your interface
internal interface IPlugin
{
int MyProperty1 {get; set;}
int MyProperty2 {get; set;}
int MyProperty3 {get; set;}
void HiddenMethod();
}
2) Implement properties/methods that you want to hide explicitly :
abstract class PluginBase : IPlugin
{
public int MyProperty1 { get; set; }
public int MyProperty2 { get; set; }
int IPlugin.MyProperty3 { get; set; }
void IPlugin.HiddenMethod() {}
}
Now you can use all your hidden methods and properties in your main solution via IPlugin interface by casting to it:
IPlugin instance = new MyConcretePlugin();
instance.MyProperty3 = 10;
instance.HiddenMethod();
IPlugin interface now is not accessible from any other solution (except one that holds it) and therefore same are for all hidden members.
you could use internal on the methods and properties that only should be available from within the assembly
public class PluginBase : IPlugin
{
// Only accessible within the same assembly
internal static int x = 0;
}
You can use InternalsVisibleToAttribute.enter link description here
I've used this pattern many times in a variety of places, usually alongside a plugin pattern.
Some example ways I've used it are for messaging systems, such as creating subscribers to various types of unrelated messages. I've also used it for generic integration workflows that each need a differently shaped context object.
Basically the pattern consists of defining a blank marker interface for a message or context. Then defining a high level workflow interface that works with the message/context interface. You can then use a factory to get a concrete instance of the workflow, and if needed, the workflow can also be responsible for parsing its message / context from a common data format.
Next, you create an abstract generic base workflow whose responsibilty is just to map calls to the interface methods, which pass around the useless marker interface, into calls to abstract methods that take the concrete version of the message/context.
Hopefully that makes sense. I'll provide a code example below. I'd love to know if this pattern has a name because I've noticed that I've used it about 4-5 times now. Also, I'm just fleshing out how to explain the pattern, so if anything about my explanation doesn't make sense please let me know that as well.
The main point is that you can have multiple classes with different method signatures that can still be called via a common interface:
End Result
public class ConcreteA : Base<MessageA>
{
public void Process(MessageA message){...}
public MessageA Parse(IDictionary data){...}
}
public class ConcreteB : Base<MessageB>
{
public void Process(MessageB message){...}
public MessageB Parse(IDictionary data){...}
}
//And both can by called by...
public void Main(){
var data = GetDataFromIntegrationSource(someContext);
IWorkflow impl = Factory.GetConcrete(someContext);
//So in your classes you're able to work with strongly typed parameters,
//But in the consuming code you still can use a common interface
//Consuming code never even knows what the strong type is.
IMessage msg = impl.Parse(data);
impl.Process(msg);
}
FULL EXAMPLE
High Level Interfaces
public interface IGenericeMarkerInterface
{
}
public interface IGenericWorkflow
{
void Process(IGenericeMarkerInterface messageOrContext);
IGenericeMarkerInterface Parse(IDictionary<string, string> commonDataFormat);
}
Abstract Base for Mapping to Concrete Methods
public abstract class GenericWorkflowBase<T> : IGenericWorkflow where T : IGenericeMarkerInterface
{
public void Process(IGenericeMarkerInterface messageOrContext)
{
Process((T)messageOrContext);
}
public IGenericeMarkerInterface Parse(IDictionary<string, string> commonDataFormat)
{
return DoParse(commonDataFormat);
}
public abstract void Process(T messageOrContext);
public abstract T DoParse(IDictionary<string, string> commonDataFormat);
}
Mapping Attributes
public class MappingAttributeUsedByFactoryAttribute : Attribute
{
public WorkflowType SomePropertyForMapping { get; set; }
}
Concrete Implementations
public class SomeRandomlyShapedMessageOrContext : IGenericeMarkerInterface
{
public int ID { get; set; }
public string Data { get; set; }
}
[MappingAttributeUsedByFactory(WorkflowType.IntegrationPartnerB)]
public class ConcreteWorkflow : GenericWorkflowBase<SomeRandomlyShapedMessageOrContext>
{
public override void Process(SomeRandomlyShapedMessageOrContext messageOrContext)
{
//TODO: process the strongly typed message
}
public override SomeRandomlyShapedMessageOrContext DoParse(IDictionary<string, string> commonDataFormat)
{
//TODO: parse the common data into the strongly typed message
}
}
Factory
public static class WorkflowFactory
{
public static IGenericWorkflow Get(WorkflowType workflow)
{
//TODO: find the concrete workflow by inspecting attributes
}
}
Example Usage
public static class Program
{
public static void Main(string[] args)
{
//this could be driven by a UI or some contextual data
var someSortOfWorkflowIdentifier = (WorkflowType)args[0];
var data = GetSomeDictionaryOfData();
var workflow = WorkflowFactory.Get(someSortOfWorkflowIdentifier);
workflow.Process(workflow.Parse(data));
}
}
Yes, it's exactly same as you named it: Marker interface
I am currently just exposing the properties through a generic interface e.g.
public interface IBaseClass
{
int ID { get; set; }
}
internal class MyBaseClass : IBaseClass
{
public MyBaseClass() { }
public int ID { get; set; }
}
public class MyExposedClass : IBaseClass
{
private MyBaseClass _base = new MyBaseClass();
public int ID
{
get { return _base.ID; }
set { _base.ID = value; }
}
}
Then in my main application I can do:
IBaseClass c = new MyExposedClass();
c.ID = 12345;
But can't do:
MyBaseClass b = new MyBaseClass();
This is my desired behaviour.
However, I was just wondering if this is the correct approach? Or if there was a better way?
If you only want to prevent instantiation you could make MyBaseClass abstract (make it's constructor protected as well - it is a good design) and have MyExposedClass derive from it. If you want to completely hide the type your approach seems fine.
This look fine to me. Making small interfaces makes it easier to write decoupled code.
I don't know if this will help, but you can make your base class protected internal. This would mean that any internal class has access to it as if it were public, or any class (from within and without the assembly) can subclass the base class. It won't prevent people from implementing their own sub class though.
Alternatively, exposing through an Interface would be the best way I'd think.
For this you can opt for explicit implementation like this:
public interface IBaseClass
{
int ID { get; set; }
}
internal class MyBaseClass : IBaseClass
{
public MyBaseClass() { }
public int IBaseClass.ID { get; set; }
}
public class MyExposedClass : IBaseClass
{
private MyBaseClass _base = new MyBaseClass();
public int IBaseClass.ID
{
get { return _base.ID; }
set { _base.ID = value; }
}
}
You can refer to a similar post C# Interfaces. Implicit implementation versus Explicit implementation
Make your base class abstract.
You could expose the interface as public, implement an internal sealed implementation of that class, and use a factory approach to build instances of the desired interface. That way the client will never know when you change your implementation, or if you have multiple implementations of the same base interface plugged in the factory. You could also eliminate the set accessors in the interface and put them in the internal implementation to only expose the properties to the outside world. That way the exterior code has to make less assumptions over your implementation and you are better isolated. Please correct me if I'm having a poor/bad image of this approach.
Edit: The factory would be public and you'd need some sort of "transfer object" to pass data to the factory. That transfer object implementation would be public, together with it's interface.
Your example seems to include a poor example of taking advantage of inheritence. Since you included a single property it and couldnt come up with a better example i am guessing that its real. I would suggest in this case forget the base class and stick the property on the derived.