I am trying to refactor some classes in a project to make them testable using interfaces and dependency injection. But I struggle with the following:
public interface IInterfaceA
{
void SomePublicMethod();
}
public class ConcreteObject : IInterfaceA
{
public void SomePublicMethod() { ... }
public void SomeOhterMethod() { ... }
public void YetAnotherMethod() { ... }
}
public class AnotherConcreteObject
{
private IInterfaceA _myDependency;
public AnotherConcreteObject( IInterfaceA myDependency )
{
_myDependency=myDependency;
}
}
So far everything is fine, pretty standard code. AnotherConcreteObject needs to call SomeOtherMethod, but I don't want other classes (e.g. in a different assembly) to be able to call SomeOtherMethod. So externally SomePublicMethod should be visible, but SomeOtherMethod should not be. Only instances of AnotherConcreteObject should be able to call SomeOtherMethod. SomeOtherMethod will e.g. set a internal property which is used later by YetAnotherMethod to determine what should happen. The internal property is set to a default value in all other cases e.g. when YetAnotherMethod is called from any other class than AnotherConcretObject.
When not using interfaces, this is possible because AnotherConcreteObject is in the same assembly as ConcreteObject so it has access to internal properties and methods. Classes in a different assembly can not set this property or call the method because they don't have access to internal properties and methods.
There are a couple of possible solutions, depending on what exactly you are doing:
1 if SomePublicMethod is public, but SomeOtherMethod is internal, then don't put them in the same class and they likely do very different things and so the separation of concerns principle comes in to play.
2 If ConcreteObject doesn't have state and doesn't cause side effects, or if you aren't going to run tests against it in parallel, ie has unit behaviour, then it may not need mocking, so access it directly.
Related
Imagine the following scenario in a Xamarin solution:
Assembly A (PCL):
public abstract class MyBaseClass
{
public MyBaseClass()
{
[...]
}
[...]
}
Assembly B (3rd Party Library):
public class SomeLibClass
{
[...]
public void MethodThatCreatesClass(Type classType){
[...]
//I want to allow this to work
var obj = Activator.CreateInstance(classType);
[...]
}
[...]
}
Assembly C (Main project):
public class ClassImplA:MyBaseClass{
[...]
}
public class ClassImplA:MyBaseClass{
[...]
}
public class TheProblem{
public void AnExample(){
[...]
//I want to block these instantiations for this Assembly and any other with subclasses of MyBaseClass
var obj1 = new ClassImplA()
var obj2 = new ClassImplB()
[...]
}
}
How can I prevent the subclasses from being instantiated on their own assembly and allow them only on the super class and the 3rd Party Library (using Activator.CreateInstance)?
Attempt 1
I though I could make the base class with an internal constructor but then, I saw how silly that was because the subclasses wouldn't be able to inherit the constructor and so they wouldn't be able to inherit from the superclass.
Attempt 2
I tried using Assembly.GetCallingAssembly on the base class, but that is not available on PCL projects. The solution I found was to call it through reflection but it also didn't work since the result of that on the base class would be the Assembly C for both cases (and I think that's because who calls the constructor of MyBaseClass is indeed the default constructors of ClassImplA and ClassImplB for both cases).
Any other idea of how to do this? Or am I missing something here?
Update
The idea is to have the the PCL assembly abstract the main project (and some other projects) from offline synchronization.
Given that, my PCL uses its own DB for caching and what I want is to provide only a single instance for each record of the DB (so that when a property changes, all assigned variables will have that value and I can ensure that since no one on the main project will be able to create those classes and they will be provided to the variables by a manager class which will handle the single instantions).
Since I'm using SQLite-net for that and since it requires each instance to have an empty constructor, I need a way to only allow the SQLite and the PCL assemblies to create those subclasses declared on the main project(s) assembly(ies)
Update 2
I have no problem if the solution to this can be bypassed with Reflection because my main focus is to prevent people of doing new ClassImplA on the main project by simple mistake. However if possible I would like to have that so that stuff like JsonConvert.DeserializeObject<ClassImplA> would in fact fail with an exception.
I may be wrong but none of the access modifiers will allow you to express such constraints - they restrict what other entities can see, but once they see it, they can use it.
You may try to use StackTrace class inside the base class's constructor to check who is calling it:
public class Base
{
public Base()
{
Console.WriteLine(
new StackTrace()
.GetFrame(1)
.GetMethod()
.DeclaringType
.Assembly
.FullName);
}
}
public class Derived : Base
{
public Derived() { }
}
With a bit of special cases handling it will probably work with Activator class , but isn't the best solution for obvious reasons (reflection, error-prone string/assembly handling).
Or you may use some dependency that is required to do anything of substance, and that dependency can only be provided by your main assembly:
public interface ICritical
{
// Required to do any real job
IntPtr CriticalHandle { get; }
}
public class Base
{
public Base(ICritical critical)
{
if (!(critical is MyOnlyTrueImplementation))
throw ...
}
}
public class Derived : Base
{
// They can't have a constructor without ICritical and you can check that you are getting you own ICritical implementation.
public Derived(ICritical critical) : base(critical)
{ }
}
Well, other assemblies may provide their implementations of ICritical, but yours is the only one that will do any good.
Don't try to prevent entity creation - make it impossible to use entities created in improper way.
Assuming that you can control all classes that produce and consume such entities, you can make sure that only properly created entities can be used.
It can be a primitive entity tracking mechanism, or even some dynamic proxy wrapping
public class Context : IDisposable
{
private HashSet<Object> _entities;
public TEntity Create<TEntity>()
{
var entity = ThirdPartyLib.Create(typeof(TEntity));
_entities.Add(entity);
return entity;
}
public void Save<TEntity>(TEntity entity)
{
if (!_entities.Contains(entity))
throw new InvalidOperationException();
...;
}
}
It won't help to prevent all errors, but any attempt to persist "illegal" entities will blow up in the face, clearly indicating that one is doing something wrong.
Just document it as a system particularity and leave it as it is.
One can't always create a non-leaky abstraction (actually one basically never can). And in this case it seems that solving this problem is either nontrivial, or bad for performance, or both at the same time.
So instead of brooding on those issues, we can just document that all entities should be created through the special classes. Directly instantiated objects are not guaranteed to work correctly with the rest of the system.
It may look bad, but take, for example, Entity Framework with its gotchas in Lazy-Loading, proxy objects, detached entities and so on. And that is a well-known mature library.
I don't argue that you shouldn't try something better, but that is still an option you can always resort to.
New to OOP here. I have defined an interface with one method, and in my derived class I defined another public method. My client code is conditionally instantiating a class of the interface type, and of course the compiler doesn't know about the method in one of the derived classes as it is not part of the underlying interface definition. Here is what I am talking about:
public interface IFileLoader
{
public bool Load();
}
public class FileLoaderA : IFileLoader
{
public bool Load();
//implementation
public void SetStatus(FileLoadStatus status)
{
//implementation
}
}
public class FileLoaderB : IFileLoader
{
public bool Load();
//implementation
//note B does not have a SetStatus method
}
public enum FileLoadStatus
{
Started,
Done,
Error
}
// client code
IFileLoader loader;
if (Config.UseMethodA)
{
loader = new FileLoaderA();
}
else
{
loader = new FileLoaderB();
}
//does not know about this method
loader.SetStatus (FileStatus.Done);
I guess I have two questions:
What should I be doing to find out if the object created at run-time has the method I am trying to use? Or is my approach wrong?
I know people talk of IOC/DI all the time. Being new OOP, what is the advantage of using an IOC in order to say, "when my app asks
for an IFileLoader type, use concrete class x", as opposed to simply
using an App.Config file to get the setting?
Referring to your two questions and your other post I'd recommend the following:
What should I be doing to find out if the object created at run-time has the method I am trying to use? Or is my approach wrong?
You don't necessarily need to find out the concrete implementation at runtime in your client code. Following this approach you kinda foil the crucial purpose of an interface. Hence it's rather useful to just naïvely use the interface and let the concrete logic behind decide what's to do.
So in your case, if one implementation's just able to load a file - fine. If your other implementation is able to the same and a bit more, that's fine, too. But the client code (in your case your console application) shouldn't care about it and just use Load().
Maybe some code says more than thousand words:
public class ThirdPartyLoader : IFileLoader
{
public bool Load(string fileName)
{
// simply acts as a wrapper around your 3rd party tool
}
}
public class SmartLoader : IFileLoader
{
private readonly ICanSetStatus _statusSetter;
public SmartLoader(ICanSetStatus statusSetter)
{
_statusSetter = statusSetter;
}
public bool Load(string fileName)
{
_statusSetter.SetStatus(FileStatus.Started);
// do whatever's necessary to load the file ;)
_statusSetter.SetStatus(FileStatus.Done);
}
}
Note that the SmartLoader does a bit more. But as a matter of separation of concerns its purpose is the loading part. The setting of a status is another class' task:
public interface ICanSetStatus
{
void SetStatus(FileStatus fileStatus);
// maybe add a second parameter with information about the file, so that an
// implementation of this interface knows everything that's needed
}
public class StatusSetter : ICanSetStatus
{
public void SetStatus(FileStatus fileStatus)
{
// do whatever's necessary...
}
}
Finally your client code could look something like the follwing:
static void Main(string[] args)
{
bool useThirdPartyLoader = GetInfoFromConfig();
IFileLoader loader = FileLoaderFactory.Create(useThirdPartyLoader);
var files = GetFilesFromSomewhere();
ProcessFiles(loader, files);
}
public static class FileLoaderFactory
{
public static IFileLoader Create(bool useThirdPartyLoader)
{
if (useThirdPartyLoader)
{
return new ThirdPartyLoader();
}
return new SmartLoader(new StatusSetter());
}
}
Note that this is just one possible way to do what you're looking for without having the necessity to determine IFileLoader's concrete implementation at runtime. There maybe other more elegant ways, which furthermore leads me to your next question.
I know people talk of IOC/DI all the time. Being new OOP, what is the advantage of using an IOC [...], as opposed to simply using an App.Config file to get the setting?
First of all separating of classes' responsibility is always a good idea especially if you want to painlessly unittest your classes. Interfaces are your friends in these moments as you can easily substitute or "mock" instances by e.g. utilizing NSubstitute. Moreover, small classes are generally more easily maintainable.
The attempt above already relies on some sort of inversion of control. The main-method knows barely anything about how to instantiate a Loader (although the factory could do the config lookup as well. Then main wouldn't know anything, it would just use the instance).
Broadly speaking: Instead of writing the boilerplate factory instantiation code, you could use a DI-Framework like Ninject or maybe Castle Windsor which enables you to put the binding logic into configuration files which might best fit your needs.
To make a long story short: You could simply use a boolean appSetting in your app.config that tells your code which implementation to use. But you could use a DI-Framework instead and make use of its features to easily instantiate other classes as well. It may be a bit oversized for this case, but it's definitely worth a look!
Use something like:
if((loader as FileLoaderA) != null)
{
((FileLoaderA)loader).SetStatus(FileStatus.Done);
}
else
{
// Do something with it as FileLoaderB type
}
IoC is normally used in situations where your class depends on another class that needs to be setup first, the IoC container can instantiate/setup an instance of that class for your class to use and inject it into your class usually via the constructor. It then hands you an instance of your class that is setup and ready to go.
EDIT:
I was just trying to keep the code concise and easy to follow. I agree that this is not the most efficient form for this code (it actually performs the cast twice).
For the purpose of determining if a particular cast is valid Microsoft suggests using the following form:
var loaderA = loader as FileLoaderA;
if(loaderA != null)
{
loaderA.SetStatus(FileStatus.Done);
// Do any remaining FileLoaderA stuff
return;
}
var loaderB = loader as FileLoaderB
if(loaderB != null)
{
// Do FileLoaderB stuff
return;
}
I do not agree with using is in the if. The is keyword was designed to determine if an object was instantiated from a class that implements a particular interface, rather than if a cast is viable. I have found it does not always return the expected result (especially if a class implements multiple interfaces through direct implementation or inheritance of a base class).
I have a dozen service classes that were built for WCF, e.g.:
public class BookingService : IBookingService
{
public void BookTheThing(int ThingID) { .. }
}
We are aiming to reuse these classes as direct libraries (not WCF) and create a separate service library which would allow us preserve and expose those existing methods and add new ones. Here are 2 possibilities I've come up with based on my limited experience:
*Option#1 - Inject original class and create identical methods to expose it's functionality:
public class BookingServiceNew : IBookingServiceNew
{
public BookingServiceNew(IBookingService service) { _baseService = service; }
public void BookTheThing(int ThingId) { _baseService.BookTheThing(ThingId); }
public bool OurNewMethod1(int ThingId) { return true; }
public int OurNewMethod2(int ThingId) { return 1; }
}
*Option#2 - Inherit original service class, which would automatically expose its methods as part of the class, and then add our own stuff
public class BookingServiceNew : BookingService, IBookingServiceNew
{
public bool OurNewMethod1(int ThingId) { return true; }
public int OurNewMethod2(int ThingId) { return 1; }
}
Option#1 seems like it will have some more code and duplication having to create a stub for every method in the implentation and interface. Option#2 seems like it could have some issues with dependency injection on the client, where working against IBookingServiceNew would only provide access to OurNewMethod1 & OurNewMethod2.
Again, these options I've come with are based on my very limited experience and I would appreciate your thoughts and suggestions on a better approach/practice/pattern to follow.
Thanks
I'd recommend going with option 1 (composition) over inheritance. Yes, this requires additional boilerplate code to expose each method of the inner service. However, this code has no logic so we're not really "repeating" anything. Furthermore, by using composition you gain a ton of flexibility down the line; if you decide you don't want to expose the same interface in IBookingServiceNew as in IBookingService you can simply remove/change those methods without modifying the original BookingService implementation. You can also easily swap in a new implementation of IBookingService (e. g. a mock in a unit test).
In contrast, using class inheritance to avoid the boilerplate saves some code in the short run, at a big cost to flexibility and maintenance. For one, you give up the ability to extend a different base class in the future. Now, your BookingService class must be designed for inheritance; you'll have to be careful about which internal methods and state are exposed to the subclass, and you need to worry about introducing conflicts with methods in the derived class. In general, the API exposed by a class which you expect to be extended is much more complex and harder for the consumer to understand than the one exposed by an interface. As a general rule, I try to avoid using class inheritance unless I will actually be making use of polymorphism (as opposed to just including methods from the base class). In this case, you're already using interfaces, so you have no need for the class polymorphism.
Finally, note that your concern about IBookingServiceNew not exposing the methods on IBookingService is easily addressed by either (1) putting those methods on IBookingServiceNew as well or (2) having IBookingServiceNew extend IBookingService.
What about extension methods?
public static class BookingServiceExtensions
{
public static bool OurNewMethod1(this IBookingService service, int ThingId)
{
...
}
}
I have a question concerning holding common code in a base class and having the derived class call it, even though the derived class's trigger method has been dispatched from the base. So, base->derived->base type call stack.
Is the following look OK, or does it smell? I have numbered the flow steps...
public abstract class LayerSuperType
{
public void DoSomething() // 1) Initial call from client
{
ImplementThis(); // 2) Polymorphic dispatch
}
protected abstract void ImplementThis();
protected void SomeCommonMethodToSaveOnDuplication(string key) // 4)
{
Configuration config = GetConfiguration(key);
}
}
public class DerivedOne : LayerSuperType
{
protected virtual void ImplementThis() // 2)
{
SomeCommonMethodToSaveOnDuplication("whatever"); // 3) Call method in base
}
}
public class DerivedTwo : LayerSuperType
{
protected virtual void ImplementThis() // 2)
{
SomeCommonMethodToSaveOnDuplication("something else"); // 3) Call method in base
}
}
That looks absolutely fine. Perfect example of why you'd use an abstract class over an interface. It's a bit like a strategy pattern and I have used this fairly regularly and successfully.
Make sure that what the class doing is still dealing with one 'concern' though, only doing one task. If your base class does repository access but the objects are representing documents, don't put the functionality in the base class, use a separate repository pattern/object.
Looks like a very simplified Template Method Pattern where your sub-classes do some specific kinds of things at the right points in the implementation of your algorithm, but the overall flow is directed by a method on the base class. You've also provided some services to your sub-classes in the form of base class methods; that's ok too as long as you're good as far as SOLID goes.
Why not public abstract void DoSomething() and forget about ImplementThis() altogether?
The only reason I can see to leave ImplementThis() is if you want to maintain a consistent interface with DoSomething() which later on down the road will allow the signature of ImplementThis() to change without a breaking change to callers.
I agree that you should maintain a single concern with the class's responsibility but from an overall OOP perspective this looks fine to me. I've done similar on many occasions.
It does smell a little that SomeCommonMethodToSaveOnDuplication is being called in two different ways. It seems to be doing two unrelated things. Why not have two methods?
I am really interested in some architectural methods. I like DI and IOC, but I don't understand costructor injection; why is it so complicated. I've written the code below which uses constructor injection:
namespace DependencyInjection
{
class Program
{
static void Main(string[] args)
{
ConstructorInjectionClass myCtx = new ConstructorInjectionClass(new PdfFormat());
myCtx.Print();
Console.Read();
}
}
public interface IFormat
{
void Print();
}
public class PdfFormat : IFormat
{
public void Print()
{
Console.WriteLine("Pdf Format Print is completed...");
}
}
// Constructor Injection
public class ConstructorInjectionClass
{
private IFormat _format;
public ConstructorInjectionClass(IFormat format)
{
_format = format;
}
public void Print()
{
_format.Print();
}
}
I've written some code below. I think it's simple.
public interface IFormat
{
void Print();
}
public class PdfFormat : IFormat
{
public void Print()
{
Console.WriteLine("Pdf Format Print is completed...");
}
}
public interface ISave
{
void Add();
}
public class Sql: ISave
{
public void Add()
{
Console.WriteLine("Adding to SQL is completed...");
}
}
// Constructor Injection
public class ConstructorInjectionClass
{
public ConstructorInjectionClass(IFormat format)
{
format.Print();
}
public ConstructorInjectionClass(ISave saver)
{
saver.Add();
}
Why should I use constructor injection? Advantages or disadvantages of these two methods?
The first example is constructor injection. You are injecting the class with the responsibility for printing into the class.
In the second example you are creating a new class with one of 2 arguments and using the argument in the constructor. This is bad for several reasons:
Your constructor should not really do significant work, this is either saving or printing in the constructor
Your different constructors are doing different this. The constructor should only create a new instance of your class.
It is not clear that the different constructors will actually do something when they are given different objects.
If you pass the objects to the constructor and then it just calls them, why would you not just have the code that is constructing this class call the methods on ISave and IPrint implementations. After all it must have them to be able to pass them to the method. If your object holds these internally then they could have been provided when your object was constructed (like in your composition root) and the client code that calls Print on your object would not need to know anything about the fact that the ISave and IPrint implementations exist,
Constructor injection is about you class asking for the dependencies it has in it's constructor, so it is clear what the dependencies are. By requiring the dependencies rather than creating them it becomes simpler to test the class as you can inject mock dependencies for testing purposes.
The first option is good, and if you want to add saving then you should add an extra argument to the constructor to take a ISave interface as well as the IPrint interface and have a method Save which will delegate to the ISave implmentation.
By having the dependencies injected and by programming to an interface it makes it easier to change the functionality later on. You could, for example, make it pring to a file easily (by changing the IPrint interface you pass in or change it to save to an xml file or a webservice by changing the ISave implementation you pass it. This make you class loosely coupled to the save and print implemenations
I would read this excellent answer for more guidance on DI/IOC
Well, as with any pattern, constructor injection should be used when and only when it's a good idea to use it. Your example code is kind of strange...
Your first example is spot on. Your class has a method called Print which has a dependency on another class to do the printing. Rather than instantiate this dependency, it requires that the dependency be supplied in its constructor. This is a classic example of the Dependency Inversion Principle. Basically: "Require, don't instantiate."
Your second example isn't quite clear, though. What is your class really doing? What's it for? It has two constructors which perform an action on their dependencies, but why? Nowhere else in the class is there a dependency on instances of these types. So why have the wrapper class in the first place? It seems more... contrived... than your first example. It's unclear what the architecture of the code is trying to accomplish, and therefore as it stands not a good use of constructor injection.
Lets say that you want to inject dependencies... you could do this via constructor injection or via property setters. I think one of the advantages to constructor injection is that IOC's use this strategy. So if you aren't sure you want to go IOC but you want to do DI then should probably use constructor injection to make the transition to IOC latter... easier... if you should change your mind...