If I have a set of interfaces which may have several implementations (i.e. in-memory, NHibernate, xml-based, etc.), is it wise to provide namespace hints in the class names themselves? For example:
MyDomain.Infrastructure.ISomeProvider
MyDomain.Infrastructure.ISomeOtherProvider
MyDomain.Infrastructure.IYetAnotherProvider
I might then have:
MyDomain.Infrastructure.Impl.MemoryBased.SomeProvider
MyDomain.Infrastructure.Impl.MemoryBased.SomeOtherProvider
MyDomain.Infrastructure.Impl.MemoryBased.YetAnotherProvider
MyDomain.Infrastructure.Impl.XmlFileBased.SomeProvider // etc...
MyDomain.Infrastructure.Impl.NHibernate.SomeProvider // etc...
vs.
MyDomain.Infrastructure.Impl.MemoryBased.MemoryBasedSomeProvider
MyDomain.Infrastructure.Impl.MemoryBased.MemoryBasedSomeOtherProvider
MyDomain.Infrastructure.Impl.MemoryBased.MemoryBasedYetAnotherProvider
MyDomain.Infrastructure.Impl.XmlFileBased.XmlSomeProvider // etc...
MyDomain.Infrastructure.Impl.NHibernate.NHibernateSomeProvider // etc...
In the second case, it’s clear which implementation I am using anywhere in my code by the class name itself, but it seems a bit redundant to group them by namespace and then include it in the class name anyway, no?
A third option might be:
MyDomain.Infrastructure.ISomeProvider
MyDomain.Infrastructure.Impl.MemoryBasedSomeProvider
MyDomain.Infrastructure.Impl.MemoryBasedSomeOtherProvider
MyDomain.Infrastructure.Impl.MemoryBasedYetAnotherProvider
MyDomain.Infrastructure.Impl.XmlSomeProvider // etc...
MyDomain.Infrastructure.Impl.NHibernateSomeProvider // etc...
I have eliminated the redundant namespaces, but now the only way to group / organize the classes is by class name prefix. I suppose I could separate them into folders and manually adjust the namespaces in any newly created files. Are there any clear advantages for one of these styles over the others?
Option #1
Would be my preferred option. You could argue that you should have them in different projects per implementation (In memory, ORM, XML) and then the required implementation could be loaded in at runtime depending on your IoC container and requirements at the time.
To mess around with namespaces and add in the type of implementation in the name of the class is overkill and will make your namespaces look pointless to external/other developers.