This question already has answers here:
How to Mock the Internal Method of a class?
(6 answers)
Closed 4 years ago.
The Situation
Suppose I have a class with an internal method:
class MyClass : IMyClass
{
public void PublicMethod() { ... }
internal void InternalMethod() { ... }
}
that implements an interface:
interface IMyClass
{
void PublicMethod() { ... }
}
And a container class that holds an instance of MyClass and other concrete classes:
class ContainerClass
{
public MyClass myClass;
...
}
ContainerClass is used by various assemblies. When used within the same assembly as MyClass the calling method can invoke containerClass.myClass.InternalMethod()
The Problem
In an effort to make things more easily mockable for testing, I am now trying to replace the ContainerClass's properties with interfaces rather than concrete classes, e.g.:
class ContainerClass
{
public IMyClass myClass;
...
}
But, if I do that, InternalMethod can no longer be invoked using containerClass.myClass.InternalMethod() because the method doesn't exist on the interface... nor can it, because it is internal. However, I cannot make the interface internal because ContainerClass is used by other assemblies as well.
Let's assume that I cannot change the internal access to that method. Is there another way?
EDIT: This is different from How to Mock the Internal Method of a class? because I am not trying to mock the internal method, I am trying to keep it exposed when replacing a concrete class (MyClass) with an interface (IMyClass).
An option is to create two interfaces, one public and one internal:
public interface IMyClassPublic
{
void PublicMethod();
}
internal interface IMyClassInternal
{
void InternalMethod();
}
Implement both of them in MyClass (you need to implement IMyClassInternal explicitly since it's internal):
public class MyClass : IMyClassPublic, IMyClassInternal
{
public void PublicMethod() { }
void IMyClassInternal.InternalMethod() { }
}
And change ContainerClass so that it exposes both interfaces separately (and probably make myClass private):
public class ContainerClass
{
private MyClass myClass;
public IMyClassPublic myClassPublic
{
get
{
return myClass;
}
}
internal IMyClassInternal myClassInternal
{
get
{
return myClass;
}
}
}
Now you can mock both of them, use the internal method as containerClass.myClassInternal.InternalMethod() and the public method as containerClass.myClassPublic.PublicMethod().
Related
I am currently refactoring some code and am dealing with reorganizing a collection of about a dozen classes with some common methods into a set of derived classes with the shared code in the base, which implements an interface exposing the methods. So far the new structure is fairly straightforward and can be summarised as follows:
public interface IContract
{
public bool MethodA();
}
public abstract class BaseClass : IContract
{
// Default implementation
public virtual bool MethodA() { return true; }
}
public class DerivedClassA : BaseClass
{
private readonly SomeServiceA service;
// Class-specific implementation (if required)
public override bool MethodA() { return service.CheckA(); }
}
Problem is that there is one derived class that contains a public method shared by no other derived class:
public class DerivedClassB : BaseClass
{
private readonly SomeServiceB service;
public override bool MethodA() { return service.CheckB(); }
public void MethodB() { service.PerformAnotherAction(); }
}
This method is currently invoked elsewhere in the codebase as below:
// Factory initialises a class of a type specified in config settings
IContract instance = ClassFactory.GetInstance();
bool ClientMethodA()
{
return instance.MethodA();
}
void ClientMethodB()
{
if (instance.GetType() == typeof(DerivedClassB))
{
((DerivedClassB)instance).MethodB();
}
}
I'd rather the invoking code not know anything about DerivedClassB but I'm not sure how to avoid the casting. My question is whether this design structure is the most optimal given this workflow, and if not, how could it be improved while adhering to SOLID principles?
For example I have the following classes:
1.
class MyClass1
{
public MyClass1 Method()
{
...
return new MyClass1();
}
}
class MyClass2
{
public MyClass2 Method()
{
...
return new MyClass2();
}
}
The methods have the same bodies that's why I want to extract the code and re-use.
2.
abstract class MyClass
{
protected void Method()
{
...
}
}
class MyClass1 : MyClass
{
public MyClass1 Method()
{
base.Method();
return new MyClass1();
}
}
class MyClass2 : MyClass
{
public MyClass2 Method()
{
base.Method();
return new MyClass2();
}
}
However since there are a lot of such methods it will be better to move the methods into the base class MyClass at all:
3.
abstract class MyClass<T>: where T : MyClass<T>
{
protected abstract T Create();
public T Method()
{
...
return Create();
}
}
class MyClass1 : MyClass<MyClass1>
{
protected override MyClass1 Create() => new MyClass1();
}
class MyClass2 : MyClass<MyClass2>
{
protected override MyClass2 Create() => new MyClass2();
}
It works fine but the contract looks too weird. Of course, I can extract something like IMyInterface and return it instead of the class. However I have to preserve the original contract because it contains specific methods as well.
Upd: So, the weird thing is in bold - class MyClass1: MyClass<MyClass1>
This is the usual so-called self-type problem (you have Method() should return the same type as the object on which it was called). Your solution #3 looks a lot like F-bounded quantification. However, this is C#, not Java, so we can do a bit better using an extension class.
You can make sure those methods only get called on subclasses of MyClass by adding a where T : MyClass bound on T.
// Put all your shared methods in generic classes in here.
public static class MyMethods
{
public static T Method<T>(this T x) where T : MyClass
{
...
}
}
Your classes don't change much, except they won't need to mention Method (or the other shared methods) at all.
public abstract class MyClass
{
...
}
public class MyClass1 : MyClass
{
...
}
public class MyClass2 : MyClass
{
...
}
Yes it looks a little bit weird to have a method which only create.
Because you have a 2 classes MyClass1 and MyClass2 which have their specific different methods and only base method is common (which you put in base class) I think you can use Abstract factory pattern.
public class ClassFactory: IClassFactory
{
public MyClass Create()
{
if (some condition)
return new MyClass1;
return new MyClass2;
}
}
class MyClass
{
protected string CommonLogic()
{
//common logic
return string;
}
}
class MyClass1 : MyClass
{
public object SpecificMethod()
{
CommonLogic();
.....
}
}
class MyClass2 : MyClass
{
public object SpecificMethod2()
{
CommonLogic();
.....
}
}
In this case you won't have duplicated code and you will have some class which one will have responsibility about creating you classes and will know when and which class return. + You will easy use it IoC here.
I hope my answer will help you.
There are some rare situations where a self-referencing type constraint may be needed, but I am not convinced that this is one of them.
It seems that you want to use the factory (Create) pattern and also have those factories return different concrete types. But at the same time you are saying that these concrete types all have something in common, specified by the base class.
The conventional approach would be to define the common features in an interface (IMyInterface as you suggested) and return that from the Create method. This would capture the polymorphic aspect of the concrete classes. Then the question is how to capture the other methods that are implemented in the concrete types. For this one can simply define additional interfaces that capture the various clusters of functionality implemented by more than one of the concrete classes.
To the extent that there are any dribs and drabs of functionality left over after you've done that, I would say handle them by casting would be the easiest -- at that point the functionality would be unique to just one of the concrete classes. If you want to fly with your eyes closed you could use the 'dynamic' type instead of casting.
Also, normally the Create method is not defined in the object instances, in other words normally objects are not their own factories. Typically they are either static or in a separate factory classes. In the current situation a bit of reflection helps deal with the fact that you have multiple derived types. There are various ways to do this besides what I show below.
So … perhaps something like this:
public interface ICommonFunctionality
{
void SomethingThatEveryoneCanDo();
// ... other common functionality
}
public interface IAdditionalFunctionality1
{
void SomethingThatAFewCanDo();
// ... other special functionality
}
public interface IAdditionalFunctionality2
{
void SomethingThatOthersCanDo();
// ... other special functionality
}
public class MyClass : ICommonFunctionality
{
static public ICommonFunctionality Create(Type derivedType)
{
if (!typeof(ICommonFunctionality).IsAssignableFrom(derivedType)) { throw new ArgumentException(); }
return derivedType.CreateInstance() as ICommonFunctionality;
}
virtual public void SomethingThatEveryoneCanDo() { /* ... */ }
}
public class MyClass1 : MyClass, IAdditionalFunctionality1
{
public void SomethingThatAFewCanDo() { /* ... */ }
}
public class MyClass2 : MyClass, IAdditionalFunctionality1, IAdditionalFunctionality2
{
public void SomethingThatAFewCanDo() { /* ... */ }
public void SomethingThatOthersCanDo() { /* ... */ }
}
public class MyClass3 : MyClass, IAdditionalFunctionality2
{
public void SomethingThatOthersCanDo() { /* ... */ }
}
public static class TypeHelpers
{
public static object CreateInstance(this Type type, bool required = true)
{
System.Reflection.ConstructorInfo ctor = type.GetConstructor(Type.EmptyTypes);
if (required && ctor == null) { throw new InvalidOperationException("Missing required constructor."); }
return ctor?.Invoke(null);
}
}
P.S. I have made the base class method virtual, this is pretty much optional depending on your situation.
I have an Interface:
public interface IMessager
{
void ShowMessage();
}
Is there any way to implement this interface using extension methods?
public static class Extensions
{
public static void ShowMessage(this MyClass e)
{
Console.WriteLine("Extension");
}
}
and a class that implement it:
public class MyClass:IMessager
{
public void ShowMessage()
{
ShowMessage(); // I expect that program write "Extension" in console
}
}
But when I run the program I get the System.StackOverflowException.
The code you posted is just a method calling itself recursively (hence the StackOverflowException).
I'm not entirely sure what you're trying to accomplish but to answer your question
Is there any way to implement this interface using extension methods?
No.
To be a bit more pragmatic about this though, if your aim is to only write your method once you have a few options:
1. Call the extension explicitly
public class MyClass:IMessager
{
public void ShowMessage()
{
Extensions.ShowMessage(this);
}
}
although as pointed out in comments, this basically defeats the point of using the extension method. Additionally there is still "boiler-plate code" such that every time you implement your interface you have to call the static method from within the method (not very DRY)
2. Use an abstract class instead of an interface
public abstract class MessengerBase
{
public void ShowMethod() { /* implement */ }
}
public class MyClass : MessengerBase {}
...
new MyClass().ShowMethod();
This issue with this though is that you can't inherit from multiple classes.
3. Use extension on the interface
public interface IMessenger { /* nothing special here */ }
public class MyClass : IMessenger { /* also nothing special */ }
public static class MessengerExtensions
{
public static void ShowMessage(this IMessenger messenger)
{
// implement
}
}
...
new MyClass().ShowMessage();
I've the following scenario
I've an Interface
public interface ImyInterface
{
void myInterfaceMethod(string param);
}
I've an Abstract Class
public abstract class myAbstractClass
{
public myAbstractClass()
{
//something valid for each inherited class
}
public void myAbstractMethod<T>(T param)
{
//something with T param
}
}
I've a class that inherits from myAbstractClass and implements ImyInterface
public class myClass : myAbstractClass, ImyInterface
{
public myClass():base()
{}
public void ThisMethodWillNeverCall()
{
// nothing to do
}
}
And, finally, I've a class where I'll create a ImyInterface object. At this point I would call myAbstractMethod, but...
public class myFinalClass
{
public void myFinalMethod()
{
ImyInterface myObj = _myContainer<ImyInterface>();
myObj.???
}
}
Obviously there isn't this method because it isn't declared into the interface.
My solution is the following
public interface ImyInterface
{
void myInterfaceMethod(string param);
void myFakeMethod<T>(T param);
}
public class myClass : myAbstractClass, ImyInterface
{
public myClass():base()
{}
public void ThisMethodWillNeverCall()
{
// nothing to do
}
//--- a fake method
public void myFakeMethod<T>(T param)
{
base.myAbstractMethod<T>(param);
}
}
Is there any other solution better than mine?
Thank you!
First of all, your naming convention is a mess. Read up on the guidelines that Microsoft have made.
It's also hard to tell what you are trying to achieve based on your example.
Back to your question:
You should only access an interface to work with that interface. Don't try to make any magic stuff with classes/interfaces to get them working together. That usually means that the class shouldn't try to implement the interface.
It's better that you create a new interface which have the features that you want and let your class implement both.
So, I'd like to hear what you all think about this.
I have a project where three different inheritance paths need to all implement another base class. This would be multiple inheritance and isn't allowed in C#. I am curious how I can implement this without code duplication.
EDIT: I don't own the three classes. The three classes are from 3rd party code. So I cannot make them all extend my base class.
Right now I am using three different classes, each one extending a different base class. Then I have the same code in each of the three abstract classes.
I could use a single interface, but I would still need to duplicate the code.
I could make some kind of static class that implements the code and then reference that in each of the 3 abstract classes. It would eliminate the duplication, but, I am not sure how I feel about this. I could implement Extensions methods on the interface, but then the interface itself would be empty and the extension methods (containing the duplicate code) would be in a totally different file, which seems not quite right. Plus I can't implement properties in extension methods...
How can I factor out the code duplication here?
EDIT, inheritance tree:
class Class1 : 3rdPartyBaseClass1 { }
class Class2 : 3rdPartyBaseClass2 { }
class Class3 : 3rdPartyBaseClass3 { }
I have code I want to be in each of the above Classes, but I cannot add it to the 3rdPartyClasses.
Create an interface that Class1, Class2, and Class3 can implement. Then put your code in extension methods so it will apply to all.
interface IMyInterface {
void Foo(); //these are the methods that these
//classes actually have in common
void Bar();
}
public class Class1 : 3rdPartyBaseClass1, IMyInterface {
// whatever
}
public static class IMyInterfaceExtensions {
public static void CommonMethod(this IMyInterface obj) {
obj.Foo();
obj.Bar();
}
}
public static class Program {
public static void Main() {
var instance = new Class1();
instance.CommonMethod();
}
}
OK, you can do something similar to my previous suggestion, and also similar to recursive's suggestion. For the functionality you require in all three of your derived classes, you can create a single Interface along with a single class (call it "Implementer" for kicks) that implements that Interface (and that has the actual code you want executed with each call).
In each of your derived classes, then, you implement the Interface and create a private instance of Implementer. In each of the interface methods, you just pass the call along to the private instance of Implementer. Because Implementer and your derived classes all implement your Interface, any changes you make to the Interface will require you to modify Implementer and the derived classes accordingly.
And all your code is in one place, except for all the lines passings the calls on to the private instance of Implementer (obviously multiple inheritance would be better than this, but you go to war with the army you have, not the army you wish you had).
Update: what about just adding a public instance of your class to each of the derived classes?
public class DerivedClass1 : ThirdPartyClass1
{
public MyClass myClass = new MyClass();
}
Or if you care who Demeter is and you get paid by LOC:
public class DerivedClass1 : ThirdPartyClass1
{
private MyClass _myClass = new MyClass();
public MyClass myClass
{
get
{
return _myClass;
}
}
}
Then you'd just call the MyClass methods like this:
DerivedClass1 dc1 = new DerivedClass1();
dc1.myClass.DoSomething();
This way, we could all go to sleep.
Similar to MusiGenesis's suggestion, if you need the functionality of the 3rd party classes but do not have to descend from them, you could use composition as follows:
class ThirdPartyBaseClass1
{
public void DoOne() {}
}
class ThirdPartyBaseClass2
{
public void DoTwo() { }
}
class ThirdPartyBaseClass3
{
public void DoThree() { }
}
abstract class Base
{
public void DoAll() { }
}
class Class1 : Base
{
public void DoOne() { _doer.DoOne(); }
private readonly ThirdPartyBaseClass1 _doer = new ThirdPartyBaseClass1();
}
class Class2 : Base
{
public void DoTwo() { _doer.DoTwo(); }
private readonly ThirdPartyBaseClass2 _doer = new ThirdPartyBaseClass2();
}
class Class3 : Base
{
public void DoThree() { _doer.DoThree(); }
private readonly ThirdPartyBaseClass3 _doer = new ThirdPartyBaseClass3();
}
This also gives you the freedom to define whatever interfaces you want and implement them on your classes.
Sounds like you need to insert the new abstract class into the inheritance tree at whatever point those three paths come together, but there really isn't enough information to tell. If you could post some of your inheritance tree, that would help a lot.
I think you may want to use composition instead of inheritance. Exactly how to do this depends on what the third party classes look like, and what your own code looks like. Some more specific code relating to your problem would be helpful, but for example, suppose you want to have three different third party GUI widgets that all need to be customized with your own initializer code.
Case 1: Suppose your third party widgets look like:
public interface IThirdPartyWidget {
public void doWidgetStuff();
}
public class ThirdPartyWidget1: ThirdyPartyWidget implements IThirdPartyWidget {
...
}
public class ThirdPartyWidget2: ThirdPartyWidget implements IThirdPartyWidget {
...
}
You can do:
public class MyWidget implements IThirdPartyWidget {
private IThirdPartyWidget delegateWidget;
public MyWidget(IThirdPartyWidget delegateWidget) {
this.delegateWidget = delegateWidget;
}
public void doWidgetStuff() {
delegateWidget.doWidgetStuff();
}
}
Case 2: Suppose you absolutely need to extend those widgets, and you have to refactor your own code:
public class MyWidget1: ThirdPartyWidget1 {
public void myMethod() {
runMyCode();
}
private void runMyCode() {
//something complicated happens
}
}
public class MyWidget2: ThirdPartyWidget2 {
public void myMethod() {
runMyCode();
}
private void runMyCode() {
//something complicated happens
}
}
This can become:
public class MyCodeRunner {
public void runMyCode() {
//...
}
}
public class MyWidget1: ThirdPartyWidget1 {
private MyCodeRunner myCode = new MyCodeRunner();
public void myMethod() {
myCode .runMyCode();
}
}
public class MyWidget2: ThirdPartyWidget2 {
private MyCodeRunner myCode = new MyCodeRunner();
public void myMethod() {
myCode .runMyCode();
}
}
Hope this makes sense!