Ok, I have a library that I just refactored a lot and have begun
introducing interfaces for various dependencies so I can separate
concerns and improve the design and testability of the classes. One of
the problems with the library is that there is an overuse of inheritance
to hide away dependancies (for example User inherits from BaseQuery
which is dependent on 3 interfaces used for data access and User also
uses a Messenger singleton which queues up message objects for batch
sending in another thread [1]). I don't want to change the API (User is
being used publicly and has a bunch of different constructors already).
Eventually I would like to get this library to be IoC pluggable and use
windsor in 2 of the apps that are using/going to use the library (in a
few months or so). The experience I have for DI is using constructors
requiring interfaces, but that is basically only on new classes I have
written since I learned my TDD ways. I am not sure how I would use
constructors in this case, but I think I have figured out how I can use
properties (again, I don't want to break the API at this point).
If I were to create properties, how difficult is the refactor to
constructors and do I even have a reason to do it? I think I want to
refactor away the odd constructors anyways (I don't think I will be
using them and they don't really make a lot of sense as they are mostly
object builders and they do strange things like call virtual methods and
perform logic across layers within the library, big smells IMO), I just
cannot do the refactoring today (the app will have live users Wednesday
and there is about 2 days worth of work in the refactorings).
[1]
A window into the library structure (only the small part I am talking
about):
interface IDatabase (has 4 implementations in the library)
interface IDbProvider (depends on IDatabase, has method to return a
database implementation, allowing me to sub in a stub database when a
real one is unavailable; this app is not using NHibernate atm, but this
interface would eventually allow me to refactor that into place without
too much difficulty, NH is eventually a goal alongside a migration to a
new database engine, 5 implementations, 2 used in BaseQuery)
interface IPipe (sort of a basic communication layer, don't worry about
it, dozens of implementations, 1 used in BaseQuery)
interface INameValueCollection (Cache, Session, Application, ...; cache
is used in BaseQuery)
interface IMessageSender (the Messenger singleton)
interface IMessage
abstract class BaseQuery (uses 2 IDbProviders 1 IPipe, 1
INameValueCollection)
class User (inherits BaseQuery, uses IMessageSender)
(19 other classes similar in structure to User but do different things
and may or may not depend on other interfaces)