I have an IDirectory
interface and a Directory
class that implements it.
I need to create an IDirectoryEnumerator
which just has a method that looks like so:
IEnumerable<IDirectory> GetDirectories();
So I created a DirectoryEnumerator
class, but I'm not sure which IDirectory
to return in GetDirectories()
, since I want to keep my code loosely-coupled.
Should I use generics with constraints to IDirectory
somehow?
Should I get it somehow through a DI container?
Should something like that be tightly-coupled and I should focus on a specific concrete type?
Or is there another better option?
Note: concrete types of IDirectory
in my example don't have any default constructors and are immutable.
You could let the concrete IDirectoryEnumerator
implementation accept some sort of factory (e.g. IDirectoyFactory
) through the constructor, and then use a parametrized method in that factory to create concrete types of IDirectory
.
This also makes testing easier and enables you to use a DI container to inject the dependencies.
EXAMPLE:
public interface IDirectoryEnumerator
{
IEnumerable<IDirectory> GetDirectories();
}
public class DirectoryEnumImpl : IDirectoryEnumerator
{
private readonly IDirectoryFactory _directoryFactory;
public DirectoryEnumImpl(IDirectoryFactory directoryFactory)
{
_directoryFactory = directoryFactory;
}
public IEnumerable<IDirectory> GetDirectories()
{
// you can use the factory here
}
}
public interface IDirectoryFactory
{
IDirectory CreateDirectory(DirectoryType directoryType);
}
public class DirectoryFactoryImpl : IDirectoryFactory
{
IDirectory CreateDirectory(DirectoryType directoryType)
{
if (directoryType == DirectoryType.DIR_A)
return new Dir_A();
// the same goes for other types.
}
}
public enum DirectoryType
{
DIR_A, DIR_B, // etc ...
}