public class Repository: NHibernateRepository
{
public Repository(ISessionFactory factory): base(fact)
// Etc….
}
public class SomeOtherClass
{
public IRepository GetRepository()
{
return ObjectFactory.GetInstance<IRepository>();
}
}
The repository class was dependent on a SessionFactory, so in the constructor of that class this was injected. This enables testing code like:[TestMethod]
public void TestTheRepository()
{
var repos = new Repository(CreateSomeTestFactory());
// perform the tests
}
However, in the production code I could not find a single line that did the same as in the above test code. So, how did StructureMap create the Repository class, i.e. how did it inject the required factory??Turned out that I had written the following sort of code:
public void DoSomeThingWithRepository()
{
// First tell StructureMap what factory to use
ObjectFactory.Configure(x => x.For<ISessionFactory>().Use(new ProductionFactory());
// Now I can let StructureMap get the repository, and have it constructed with the factory I just configured
var repos = ObjectFactory.GetInstance<IRepository>();
}
That means that the following should be regarded as an anti-pattern:public class Repository
{
public Repository()
{
base.SetFactory(ObjectFactory.GetInstance<ISessionFactory>());
}
}
Besides the ugliness of the code, it creates an unnecessary dependance on StructureMap. In general, classes that rely on other classes should be constructed with those classes. Preferably, interfaces of those classes so the constructed class can remain blissfully unaware about the implementation details of the classes it depends on.See also blog by Jeremy Miller: IOC antipattern
No comments:
Post a Comment