I have a multilevel inheritance structure that consists of three classes: Base, Child70, and Child80.
class Base {
virtual public System.String Version
{
get { return m_strVersion; }
}
}
class Child70 : Base {
public override System.String Version
{
get { return "70" }
}
}
class Child80 : Child70 {
public override System.String Version
{
get { return "80" }
}
}
The idea is that each time I create an instance of child class with specific version, I will have methods to handle that specific version. However, I feel this multilevel inheritance structure is unnecessary. Is there a way to merge them into one class and having similar functionalities? Thanks in advance if anyone could help me with it.
Related
Hi I have a a MEF container which detects metadata attributes and I would like to expand on this and allow classes to implement additional intefaces (in the example below, where i want to implement an additional interface IPluginSettings).
The module GUID identifier is critical as it is reconciled with a module ID in my database application, if I query the MEF container for my imported interfaces I can loop through them:
foreach (Lazy<T,IPluginMetadata> moduleInAssembly in m_Container.GetExports<T, IPluginMetadata>();)
{
T value = moduleInAssembly.Value; // instantiate an object of type T to test for implementations of other interfaces...
if (value is IPluginSettings)
{
// this module also contains an interface for settings!
}
Guid moduleInAssemblyId = Guid.Parse(moduleInAssembly.Metadata.PluginID);
}
I have some questions:
1) In the above scenario, I have to instantiate the class to test if I it implements a specific interface, is there a better way of doing this with Metadata and enhance the PluginExportAttribute to accept a list of secondary interface types?
2) How can I tell MEF container to import types that only have the PluginExportAttribute?
3) Or instead of having each plugin interface flexilbe/free to declare its own interface, would i be better off for plugins to implement a well-known plugin interface which contained a factory to instantiate the specific plugin interface? (Example of what i am asking is at the bottom of the code - last section)
4) Thanks to one proposed answer i am using code structured as per question 4 snipit below and it works! Out of curiosity, is there anyway to merge multiple seperate Export attributes into the PluginExportAttribute, perhaps in a constructor parameter to take a list of additional types to register?
Thanks,
Chris
public interface IPluginMetadata
{
string PluginID { get; }
}
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class PluginExportAttribute : ExportAttribute, IPluginMetadata
{
public PluginExportAttribute(Type t, string guid)
: base(t)
{
PluginID = guid.ToUpper();
}
public string PluginID { get; set; }
}
[PluginExport(typeof(IAccountsPlugin),"BE112EA1-1AA1-4B92-934A-9EA8B90D622C")]
public class BillingModule : IAccountsPlugin, IPluginSettings
{
// my class contents
}
or would i be better of doing something like this...?
// or would i be better of by implementing a plugin base, and getting instances of the plugin via a secondary factory?
public interface IWellKnownPluginBase
{
Guid PluginID { get; }
Version Version { get; }
IPluginSettings Settings { get; }
Type GetPluginInterfaceType { get; }
object PluginInterfaceFactory();
}
public interface IMyPlugin
{
void DoSomethingCool();
}
[Export(typeof(IWellKnownPluginBase))]
public class MyPluginWrapper : IWellKnownPluginBase
{
private readonly string ID = "BE112EA1-1AA1-4B92-934A-9EA8B90D622C";
Guid PluginID { get { return Guid.Parse(ID); } }
Version Version { get {return new Version(1,0,0); } }
IPluginSettings Settings { get { return new SomethingThatImplementsIPluginSettings(); }
Type GetPluginInterfaceType { get { return gettype(IMyPlugin); }
object PluginInterfaceFactory() { return new MyPlugin(); }
class MyPlugin : IMyPlugin
{
void DoSomethingCool() {}
}
}
Question 4 - can PluginExport be rewritten to register multiple interfaces with a list of interfaces in the constructor?
[Export(typeof(IPluginSettings))]
[PluginExport(typeof(IAccountsPlugin),"BE112EA1-1AA1-4B92-934A-9EA8B90D622C")]
public MyModule class : IModule, IPluginSettings
{
}
In the above scenario, I have to instantiate the class to test if I it implements a specific interface, is there a better way of doing this with Metadata and enhance the PluginExportAttribute to accept a list of secondary interface types?
Normally you would do this by having multiple exports:
[Export(typeof(IPluginSettings))]
[Export(typeof(IModule))]
public class MyModule : IModule, IPluginSettings
{
}
Instead of checking whether an interface is present, the consumer (i.e. the importer, or in your case the caller of GetExports) can then just ask for the correct interface.
Is there a tool that can generate extract and generate interfaces for existing classes?
I know Visual Studio will extract an Interface for an existing class. However, I would also like to generate a wrapper class that implements that functionality.
I believe this would help tremendously for unit testing.
Example Existing Class:
public class ThirdPartyClass
{
public void Method1(){}
public void Method2(){}
}
This can be generated by Visual Studio (Extract Interface):
public interface IThirdPartyClass
{
void Method1();
void Method2();
}
I would like to go one step further:
public class ThirdPartyClassWrapper : IThirdPartyClass
{
private tpc = new ThirdPartyClass();
public void Method1()
{
tpc.Method1();
}
public void Method2()
{
tpc.Method2();
}
}
Update:
This would be especially useful for static classes. As Morten points out I can just use a stub, however, I would like to break up my coupling if possible.
Found a way around it for non-sealed classes.
1 - Inherit from the external class
class MyWrapper : ExternalClass
2 - Extract interface for all public methods
class MyWrapper : ExternalClass, IExternalClass
3 - Remove the inheritance from the external class
class MyWrapper : IExternalClass
4 - You will get a hint on the class name about members from the interface not being implemented. Alt + Enter on it and let Resharper automatically implement them
5 - Use this code template to wrap properties
get { return $INNERCOMPONENT$.$NAME$; }
set { $INNERCOMPONENT$.$NAME$ = value; }
6 - Use this code template to wrap methods
return $INNERCOMPONENT$.$NAME$($SIGNATURE$);
I don't know a tool that would do that for you.
You probably know, but Visual Studio goes just half step further - it can provide empty implementation of interface. I would stop there if it is one time task.
Depending on actual goal using some other way may work - i.e. for testing you can use mocking frameworks - usually there is a way to wrap existing class and override some methods as needed.
Another really slick way of doing this is to use Resharper to generate the "Delegating members" for you as described here: https://stackoverflow.com/a/2150827/1703887
Steps:
Create a new class that inherits from the class you want to wrap with a private variable of that class' type:
public class ThirdPartyClassWrapper : ThirdPartyClass
{
private ThirdPartyClass _ThirdPartyClass;
}
Do a Alt-Insert in/on the class to use Resharper to generate "Delegating members". Choose the methods you want to expose and pass through to the private variable.
If you have the free version of the GhostDoc extension installed you can highlight all of the created properties, methods, etc. and do a Ctrl-D to automatically grab all of the documentation from the base class and put it on the new members. (Resharper can do this too but I think you'd have to put "new" on each item which would then allow you to Alt-Enter and choose "Add xml-doc comments" from the Resharper popup menu).
You can then delete the base class and do some additional cleanup in case the method/property signatures expose any other types that you need to wrap.
What you are looking for is a stub, this can be done either by making your own stub implementation of the interface, or by using a mocking framework like Rhinomocks. Wrapping a difficult class in another class for testpurposes does nothing good for you.
Regards
Morten
I strongly suggest you look into a mocking framework like Fakeiteasy.
But to give you exactly what you asked for see below. I suspect ReSharper didn't have this operation when others answered.
add the interface to the class you wish to be the wrapping class
class MyWebElement : IWebElement { }
Find/Click "Delegate implementation of "YourInterfaceHere" to a new field
Select your options
Click finish and enjoy your new class
class MyWebElement : IWebElement
{
private IWebElement _webElementImplementation;
public IWebElement FindElement(By #by)
{
return _webElementImplementation.FindElement(#by);
}
public ReadOnlyCollection<IWebElement> FindElements(By #by)
{
return _webElementImplementation.FindElements(#by);
}
public void Clear()
{
_webElementImplementation.Clear();
}
public void SendKeys(string text)
{
_webElementImplementation.SendKeys(text);
}
public void Submit()
{
_webElementImplementation.Submit();
}
public void Click()
{
_webElementImplementation.Click();
}
public string GetAttribute(string attributeName)
{
return _webElementImplementation.GetAttribute(attributeName);
}
public string GetCssValue(string propertyName)
{
return _webElementImplementation.GetCssValue(propertyName);
}
public string TagName
{
get { return _webElementImplementation.TagName; }
}
public string Text
{
get { return _webElementImplementation.Text; }
}
public bool Enabled
{
get { return _webElementImplementation.Enabled; }
}
public bool Selected
{
get { return _webElementImplementation.Selected; }
}
public Point Location
{
get { return _webElementImplementation.Location; }
}
public Size Size
{
get { return _webElementImplementation.Size; }
}
public bool Displayed
{
get { return _webElementImplementation.Displayed; }
}
}
I have a situation where I have 2 Activity objects (let's say empty and scheduled activity, not controlled by me) that share a couple of behaviors, like the person who booked the activity, the room where that activity takes place, activity type, subject etc.
I created two wrappers objects (EmptyWrapper and ScheduledWrapper) that have a super class ActivityWrapper that implements some methods common to both childs and has some abstract methods/properties for the child wrappers to respond accordingly. They are very much alike in behavior but there is one crucial difference, you can only schedule activities if it is an empty slot! The structure is something like this (very simplified code):
public class EmptyWrapper : AppWrapper
{
EmptySlot _emptySlot;
public EmptySlotWrapper(EmptySlot emptySlot) : base()
{
this._emptySlot = emptySlot;
}
public override string Id
{
get { return _emptySlot.AgendaId; }
}
public override string Room;
{
get{ return _emptySlot.Room;}
}
public override string Person
{
get{ return _emptySlot.Person;}
}
public override string AppType;
{
get{ return "Empty";}
}
public override bool IsAppSlot()
{
return false;
}
public override bool IsEmptySlot()
{
return true;
}
public override bool CanPerformOperations()
{
return true;
}
public void ReserveApp(ObjWithActivityInfo actObj)
{
(...)
}
}
The ActivityWrapper is similar but the object wrapped around is different, the bools return true for IsAppSlot, false for IsEmptySlot and false for CanPerformOperations and there is no ReserveApp() method.
Next is the base class:
public abstract class AppWrapper
{
public abstract string Collaborator { get; }
public abstract string Room { get; }
public abstract string AppType { get;}
public AppWrapper()
{ }
public abstract bool IsAppSlot();
public abstract bool IsEmptySlot();
public abstract bool CanPerformOperations();
public virtual string GetTextToShow()
{
return Person + " - " + Room;
}
(...)
}
In my code I wanted to reference only the ActivityWrapper, because for the general operations (show the info and appearance) I don't need the implementations. The problem rises when I need to book activities for empty slots. In that point, in my code, I cast the AppointmentWrapper to the EmptyWrapper and reserve the slot for the activity (it is still an EmptySlot but it's reserved to the selected activity), otherwise, if the cast was unsucessful I don't do anything because it was not the correct Activity Type.
Is this correct, or should I implement the ReserveActivity() method in both wrappers and have the ActivityWrapper do nothing?
Or should I do this in another way? Maybe to alter the structure of the classes?
Sorry for the long text.
There is no point in adding a function to a class that does not require it. It would defeat the point of your inheritance.
I'd do a safe cast ...
var i = obj as theClass
and then test for null. I'd use a bit of linq to select all o the objects that have the property you defined to indicate what type they are set to true.
You could do it the other way and save yourself the cast and test, but it means the design is less obvious to an outsider.
I think its a matter of taste but prefer the way you did it. I am not sure i like the bool properties to identify the type though. What if you inherit off the base class again? Besides you can cast to identify the type - which with a deeper object structure may be more useful.
I agree with your desire to work with a collection of the abstract class though.
In the several occasions that I had to deal with a similiar problem, I tend to think that it's really more elegant to create Interfaces for recognizing common functionailty for several objects then to create abstract methods which the inheriting classes will implement the way you mentioned.
e.g.
public interface IAppSlotContainer
{
void relevant_Method_When_ObjectIsAppSlot();
}
public interface IEmptySlotContainer
{
void relevant_Method_When_ObjectIsEmptySlot();
}
public class EmptyWrapper : AppWrapper, IAppSlotContainer, IEmptySlotContainer
{
public EmptyWrapper(EmptySlot emptySlot) : base()
{
this._emptySlot = emptySlot;
}
public override string Id
{
get { return _emptySlot.AgendaId; }
}
public void relevant_Method_When_ObjectIsEmptySlot()
{
}
public void relevant_Method_When_ObjectIsAppSlot()
{
}
}
Then instead of overwriting the abstract method "IsEmpty" and implementing it as "return true", just check whether the object is an instance of IEmptySlotContainer, cast it to that interface, and execute the interface related command.
it is far more generic and elegant for my taste...
Hope this helps...
Just the 5 minute overview would be nice....
public abstract class MyBaseController {
public void Authenticate() { var r = GetRepository(); }
public abstract void GetRepository();
}
public class ApplicationSpecificController {
public override void GetRepository() { /*get the specific repo here*/ }
}
This is just some dummy code that represents some real world code I have (for brevity this is just sample code)
I have 2 ASP MVC apps that do fairly similar things.
Security / Session logic (along with other things) happens the same in both.
I've abstracted the base functionality from both into a new library that they both inherit. When the base class needs things that can only be obtained from the actual implementation I implement these as abstract methods. So in my above example I need to pull user information from a DB to perform authentication in the base library. To get the correct DB for the application I have an abstract GetRepository method that returns the repository for the application. From here the base can call some method on the repo to get user information and continue on with validation, or whatever.
When a change needs to be made to authentication I now only need to update one lib instead of duplicating efforts in both. So in short if you want to implement some functionality but not all then an abstract class works great. If you want to implement no functionality use an interface.
Just look at the Template Method Pattern.
public abstract class Request
{
// each request has its own approval algorithm. Each has to implement this method
public abstract void Approve();
// refuse algorithm is common for all requests
public void Refuse() { }
// static helper
public static void CheckDelete(string status) { }
// common property. Used as a comment for any operation against a request
public string Description { get; set; }
// hard-coded dictionary of css classes for server-side markup decoration
public static IDictionary<string, string> CssStatusDictionary
}
public class RequestIn : Request
{
public override void Approve() { }
}
public class RequestOut : Request
{
public override void Approve() { }
}
Use of abstract method is very common when using the Template Method Pattern. You can use it to define the skeleton of an algorithm, and have subclasses modify or refine certain steps of the algorithm, without modifying its structure.
Take a look at a "real-world" example from doFactory's Template Method Pattern page.
The .NET Stream classes are a good example. The Stream class includes basic functionality that all streams implement and then specific streams provide specific implementations for the actual interaction with I/O.
The basic idea, is to have the abstract class to provide the skeleton and the basic functionality and just let the concrete implementation to provide the exact detail needed.
Suppose you have an interface with ... +20 methods, for instance, a List interface.
List {interface }
+ add( object: Object )
+ add( index:Int, object: Object )
+ contains( object: Object ): Bool
+ get( index : Int ): Object
+ size() : Int
....
If someone need to provide an implementation for that list, it must to implement the +20 methods every time.
An alternative would be to have an abstract class that implements most of the methods already and just let the developer to implement a few of them.
For instance
To implement an unmodifiable list, the programmer needs only to extend this class and provide implementations for the get(int index) and size() methods
AbstractList: List
+ get( index: Int ) : Object { abstract }
+ size() : Int { abstract }
... rest of the methods already implemented by abstract list
In this situation: get and size are abstract methods the developer needs to implement. The rest of the functionality may be already implemented.
EmptyList: AbstractList
{
public overrride Object Get( int index )
{
return this;
}
public override int Size()
{
return 0;
}
}
While this implementation may look absurd, it would be useful to initialize a variable:
List list = new EmptyList();
foreach( Object o: in list ) {
}
to avoid null pointers.
Used it for a home-made version of Tetris where each type Tetraminos was a child class of the tetramino class.
For instance, assume you have some classes that corresponds to rows in your database. You might want to have these classes to be considered to be equal when their ID is equal, because that's how the database works. So you could make the ID abstract because that would allow you to write code that uses the ID, but not implement it before you know about the ID in the concrete classes. This way, you avoid to implement the same equals method in all entity classes.
public abstract class AbstractEntity<TId>
{
public abstract TId Id { get; }
public override void Equals(object other)
{
if (ReferenceEquals(other,null))
return false;
if (other.GetType() != GetType() )
return false;
var otherEntity = (AbstractEntity<TId>)other;
return Id.Equals(otherEntity.Id);
}
}
I'm not a C# guy. Mind if I use Java? The principle is the same. I used this concept in a game. I calculate the armor value of different monsters very differently. I suppose I could have them keep track of various constants, but this is much easier conceptually.
abstract class Monster {
int armorValue();
}
public class Goblin extends Monster {
int armorValue() {
return this.level*10;
}
}
public class Golem extends Monster {
int armorValue() {
return this.level*this.level*20 + enraged ? 100 : 50;
}
}
You might use an abstract method (instead of an interface) any time you have a base class that actually contains some implementation code, but there's no reasonable default implementation for one or more of its methods:
public class ConnectionFactoryBase {
// This is an actual implementation that's shared by subclasses,
// which is why we don't want an interface
public string ConnectionString { get; set; }
// Subclasses will provide database-specific implementations,
// but there's nothing the base class can provide
public abstract IDbConnection GetConnection() {}
}
public class SqlConnectionFactory {
public override IDbConnection GetConnection() {
return new SqlConnection(this.ConnectionString);
}
}
An example
namespace My.Web.UI
{
public abstract class CustomControl : CompositeControl
{
// ...
public abstract void Initialize();
protected override void CreateChildControls()
{
base.CreateChildControls();
// Anything custom
this.Initialize();
}
}
}
First of all let me just say that I am new to nHibernate so if the answer to this is obvious forgive me.
I have an abstract base class with all it's members abstract.
public abstract class BallBase
{
public abstract RunsScored { get; }
public abstract IsOut { get; }
public abstract IsExtra { get; }
public abstract GetIncrement();
}
And concrete implementations like
public class WideBall : BallBase
{
public override RunsScored
{
private int m_RunsScored = 1;
public WideBall(): base()
{ }
public WideBall(int runsScored) : base()
{
m_RunsScored = runsScored;
}
public override int RunsScored
{
get
{
return m_RunsScored;
}
}
public override bool IsOut
{
get
{
return false;
}
}
public override bool IsExtra
{
get
{
return true;
}
}
public override int GetIncrement()
{
// add 0 to the balls bowled in the current over
// a wide does not get added to the balls bowled
return 0;
}
}
}
I want to use nHibernate to persist the concrete classes, but apparently all public members of the class need to be virtual.
Is there any way to continue with my base class approach?
Have a look at the C# documentation, these properties are virtual. You don't have to do anything special, you can just go on.
Thats correct if you want to utilise NHibernates ability to implement lazy loading then you need to make public members virtual.
What you can do is set the attribute lazy=false in the class tag and if you want any particular member (generally bags, lists etc) lazy then set the lazy attribute for that member to lazy=true and make its corresponding member virtual.
I've approached it this way a number of times no problem.
Yes, but the specifics will depend on how you prefer to set up your database schema. Take a look at section 8 in the NHibernate documentation. We're using <joined-subclass> and it's saved us an enormous pile of code.
You don't have to use lazy-loading if you don't want. To turn off lazy-loading for your mapped class, you can add lazy="false" to your class mapping (the .hbm.xml file).
By the way, I assume you have a specific reason for a purely abstract base class instead of an interface?