Where should I store collections of objects to facilitate DI / testing? - c#

I am trying to figure out where to store collections of objects that are retreived from a database that are necessary for the application to function. For example, I am trying to re-design a reporting application that uses Report and Parameter objects. These objects are stored in a database in XML format. At the simplest level, a collection of the definitions could be stored as a Dictionary<string, string> (object key, object definition XML).
I want to implement a factory pattern to handle the creation of these objects from their XML definitions.
IReport GetReport(string reportName)
IParameter GetParameter(string parameterName)
These methods require the factory to store the collections of reports and parameters.
So, my questions are:
Should the factory store the collection of objects at all or should it only be responsible for creating the objects from the definition, changing the method to IReport GetReport(string reportDefinition)
If the factory should store the objects, should I simple inject the collections into the constructor of the factory class?
Unit testing - If I go the route of #2, I suppose I would just inject my test collections into the factory, right?

You can structure this in many ways which all adhere to the SRP (Single Responsibility Principle).
One way is as follows: have one interface, IReportLoadingService, with a method which takes in the report identifier, and returns the IReport instance.
An implementation of this IReportLoadingService can have an IReportDefinitionRetrievalService as a dependency, e.g.
public class ReportLoadingService : IReportLoadingService
{
private readonly IReportDefinitionRetrievalService _definitionService;
public ReportLoadingService(IReportDefinitionRetrievalService definitionService)
{
_definitionService = definitionService;
}
public IReport GetReport(string reportName)
{
var reportDefinition = definitionService.GetDefinition(reportName);
return GenerateReportFromDefinition(reportDefinition);
}
private IReport GenerateReportFromDefinition(string definition)
{
// Logic to construct an IReport implementation
}
}
The live implementation of the IReportDefinitionRetrievalService will access the database and return the XML. Now your ReportLoadingService has the responsibility of populating IReport instances while another service has the responsibility of actually obtaining the report definition.
For unit testing, you can create a Mock of the IReportDefinitionRetrievalService which does whatever you want (e.g. looking up the definition in a dictionary). Take a look at Moq for a good mocking framework. It will allow you to do things like this:
[Test]
public void GetReportUsesDefinitionService()
{
var mockDefinitionService = new Mock<IReportDefinitionRetrievalService>();
mockDefinitionService.Setup(s => s.GetDefinition("MyReportName")).Returns("MyReportDefinition");
var loadingService = new ReportLoadingService(mockDefinitionService.Object);
var reportInstance = loadingService.GetReport("MyReportName");
// Check reportInstance for fields etc
// Check the definition service was used to load the definition
mockDefinitionService.Verify(s => s.GetDefinition("MyReportName"), Times.Once());
}

Your application should be persistent ignorant, so your report factory (or repository would be a better term for a facade over a data store, actually it's a Data Access Object not really a repository) should not take a report definition format.
The Get method should take a unique identifier for the report (should this be report name?) and return a DTO type that has all of the values for the report entity.
You can use an abstract factory pattern to have different implementations of your repository, one that does the XML deserialization, and a mock implementation for unit tests.
Your repositories don't need to store the collections in memory if you already have a database as the data store, although you might want to add caching to your repository, which again is easier to switch out if your application is working against abstractions.

1.Should the factory store the collection of objects at all or should it only be responsible for creating the objects from the definition,
changing the method to IReport GetReport(string reportDefinition)
None of the above. A factory is a concrete implementation selector. It's implemented as a static method which instantiates a concrete object based upon the input. You have done the job of decoupling correctly with an interface and a name. Stop there.
static IReport GetReport(string reportName)
IReport concreteReport = Factory.GetReport("myReportName")
Testing a factory via a unit test is straight forward. You can create an array of report names and check the IReport is the correct implementation via reflection or some arbitrary known Assertion. Dependency Injection is a different topic alltogether.

Related

SimpleInjector ctor injection mix registered types and simple values

How do I register types which take another registered type as a parameter and also simple types (like an integer)?
public interface IDeviceManager
{
// implementation omitted.
}
public class DeviceManager : IDeviceManager
{
public DeviceManager(IDeviceConfigRepository configRepo, int cacheTimeout)
{
// implementation omitted
}
}
I do have a container registration for the IDeviceConfigRepository. That's ok. But how do I create an instance of DeviceManager with the configured dependency and passing along an integer of my choice in composition root?
I thought about creating a factory.
public class DeviceManagerFactory : IDeviceManagerFactory
{
private readonly Container _container;
public DeviceManagerFactory(Container container)
{
_container = container;
}
public DeviceManager Create(int minutes)
{
var configRepo = _container.GetInstance<IDeviceConfigurationRepository>();
return new DeviceManager(configRepo, minutes);
}
}
This is pretty simple.
However now I do not have a registration for DeviceManager which is the type I ultimately need. Should I change these dependencies to the factory instead?
public class ExampleClassUsingDeviceManager
{
private readonly DeviceManager _deviceManager;
public ExampleClassUsingDeviceManager(DeviceManager deviceManager, ...)
{
_deviceManage = deviceManager;
}
// actions...
}
For this to work and to avoid circular dependencies I would probably have to move the factory from the "application" project (as opposed to class libraries) where the composition root is to the project where the DeviceManager is implemented.
Is that OK? It would of course mean passing around the container.
Any other solutions to this?
EDIT
In the same project for other types I am using parameter objects to inject configuration into my object graph. This works OK since I only have one class instance per parameter object type. If I had to inject different parameter object instances (for example MongoDbRepositoryOptions) into different class instances (for example MongoDbRepository) I would have to use some kind of named registration - which SimpleInjector doesn't support. Even though I only have one integer the parameter object pattern would solve my problem. But I'm not too happy about this pattern knowing it will break as soon as I have multiple instances of the consuming class (i.e. MongoDbRepository).
Example:
MongoDbRepositoryOptions options = new MongoDbRepositoryOptions();
MongoDbRepositoryOptions.CollectionName = "config";
MongoDbRepositoryOptions.ConnectionString = "mongodb://localhost:27017";
MongoDbRepositoryOptions.DatabaseName = "dev";
container.RegisterSingleton<MongoDbRepositoryOptions>(options);
container.RegisterSingleton<IDeviceConfigurationRepository, MongoDbRepository>();
I am excited to hear how you deal best with configurations done at composition root.
Letting your DeviceManagerFactory depend on Container is okay, as long as that factory implementation is part of your Composition Root.
Another option is to inject the IDeviceConfigRepository into the DeviceManagerFactory, this way you can construct a DeviceManager without the need to access the container:
public class DeviceManagerFactory : IDeviceManagerFactory {
private readonly IDeviceConfigurationRepository _repository;
public DeviceManagerFactory(IDeviceConfigurationRepository repository) {
_repository = repository;
}
public DeviceManager Create(int minutes) {
return new DeviceManager(_repository, minutes);
}
}
However now I do not have a registration for DeviceManager which is the type I ultimately need. Should I change these dependencies to the factory instead?
In general I would say that factories are usually the wrong abstraction, since they complicate the consumer instead of simplifying them. So you should typically depend on the service abstraction itself (instead of depending on a factory abstraction that can produces service abstraction implementations), or you should inject some sort of proxy or mediator that completely hides the existence of the service abstraction from point of view of the consumer.
#DavidL points at my blog post about runtime data. I'm unsure though whether the cacheTimeout is runtime data, although you seem to be using it as such, since you are passing it in into the Create method of the factory. But we're missing some context here, to determine what's going on. My blog post still stands though, if it is runtime data, it's an anti-pattern and in that case you should
pass runtime data through method calls of the API
or
retrieve runtime data from specific abstractions that allow resolving runtime data.
UPDATE
In case the value you are using is an application constant, that is read through the configuration file, and doesn't change during lifetime of the application, it is perfectly fine to inject it through the constructor. In that case it is not a runtime value. There is also no need for a factory.
There are multiple ways to register this in Simple Injector, for instance you can use a delegate to register the DeviceManager class:
container.Register<DeviceManager>(() => new DeviceManager(
container.GetInstance<IDeviceConfigRepository>(),
cacheTimeout: 15));
Downside of this approach is that you lose the ability of Simple Injector to auto-wire the type for you, and you disable Simple Injector's ability to verify, diagnose and visualize the object graph for you. Sometimes this is fine, while other times it is not.
The problem here is that Simple Injector blocks the registration of primitive types (because they cause ambiguity) while not presenting you with a clean way to make the registration. We are considering (finally) adding such feature in v4, but that doesn't really address your current needs.
Simple Injector doesn't easily allow you to specify a primitive dependency, while letting the container auto-wire the rest. Simple Injector's IDependencyInjectionBehavior abstraction allows you to override the default behavior (which is to disallow doing this). This is described here, but I usually advice against doing this, because it is usually requires quite a lot of code.
There are basically two options here:
Abstract the specific logic that deals with this caching out of the class and wrap it in a new class. This class will have just the cacheTimeout as its dependency. This is of course only useful when there actually is logical to abstract and is usually only logical when you are injecting that primitive value into multiple consumers. For instance, instead of injecting a connectionstring into multiple classes, you're probably better of injecting an IConnectionFactory into those classes instead.
Wrap the cacheTimeout value into a complex data container specific for the consuming class. This enables you to register that type, since it resolves the ambiguity issue. In fact, this is what you yourself are already suggesting and I think this is a really good thing to do. Since those values are constant at runtime, it is fine to register that DTO as singleton, but make sure to make it immutable. When you give each consumer its own data object, you won't have to register multiple instances of those, since they are unique. Btw, although named registations aren't supported, you can make conditional or contextual registrations using RegisterConditional and there are other ways to achieve named registrations with Simple Injector, but again, I don't think you really need that here.

Simple Factory with reflection C#

Simple factory using reflection involves storing (registering) various type names with their corresponding class type in a hash table, then using this hash table for generating objects in the factory.
interface Product
{
void foo();
}
class ProductFactory
{
HashTable m_RegisteredProducts = new HashTable();
public void registerProduct(string productID, Type p) {
m_RegisteredProducts.add(productID, p);
}
public Product createProduct(string productID){
return (Product) new m_RegisteredProducts[productID];
}
}
I'm not clear on when does the process of registering a new type happen since all types to be used are to be loaded into the hash table at runtime. Where is the call to registerProduct() to be made?
Calling registerProduct() for all different classes at a single place inside ProductFactory class doesn't make sense since it would defeat the purpose of using reflection over naive switch/case method.
If registerProduct() is called inside the class definition of all classes implementing the interface, then an instance of the class is created after/using the Factory hence will always give an error.
Your code doesn't do reflection as it's expecting an instance implementing the Product interface, not a type. You would need addProduct to take a Type instance, check if it implements the Product interface, then dynamically create instances of it in createProduct (using something like type.GetConstructor(<constructor signature>).Invoke(<arguments>);)
Here's an article I wrote a long time ago on something similar: http://blixt.org/2009/06/05/getting-types-implementing-class-or-interface
Calling registerProduct() for all different classes at a single place inside ProductFactory class doesn't make sense since it would defeat the purpose of using reflection over naive switch/case method.
Reflection is useful when extended product classes are added into a location (say a plug-ins directory). You have a list of strings to identify the supported plug-ins that can either be defined in a text file (application properties, which provides an added layer of security) or by (via reflection) scanning said plug-ins directory (less secure if someone can drop a hacked product in there). Disclaimer: I've never done this in C#, but it works well in Java. Apart from new product code and eventually modifying the properties file, there is no modification to the application code.
If registerProduct() is called inside the class definition of all classes implementing the interface, then an instance [of] the class is created after/using the Factory hence will always give an error.
I'm not sure that's always the strategy of the code in your question (where is it from?). You might want to read more about the different strategies of reflection combined with simple factory at http://www.codeproject.com/Articles/37547/Exploring-Factory-Pattern
It depends. There are different scenarios that call for different strategies.
One strategy that I saw quite often if all product types are defined in the same assembly (or a list of assemblies) you could call something like this:
var productTypes= from t in Assembly.GetExecutingAssembly().GetTypes()
where t.GetInterfaces().Contains(typeof(IProduct));
and then call registerProduct() for every element in productTypes.

Using Autofac and Moqs with Delegate Factories

I am trying to unit test a class that uses factory injection. I have a class that instantiates two copies of the same object (with different config) to control hardware. I'm trying to test the behaviour of the classes while simulating the hardware calls.
I've injected a set of factory delegates into the constructors so that the class can instantiate the hardware classes as required. However I just can't work out how to control or create factory methods within the Autofac.Extras.Moq package. It seems that this functionality isn't supported in the package.
I'm looking for an equivalent call to :
mock.Provide<IHWController>(//created by factory delegate)
I want to create a specific mock object with behaviour, based on the parameters used to instantiate the HWcontroller. Is what I'm trying to do even possible?
class SystemUnderTest
{
SystemUnderTest(Ia a, Ib b, Ic c,
/** 15 other things **/
Func<Func<Uri, IHwController>, HwType, IHwManager> HwManagerFactory,
Func<Uri, IHwController> HwControllerFactory)
{
}
}
class HwManager()
{
public Func<HwType, Func<Uri, HwController>, HwManager> Factory;
public HwManager(HwType type, Func<Uri, HwController> ControlFactory)
{
//Constructor
}
}
The code I'm unit testing creates Managers of controllers. The controller is the hardware layer, but I'm testing complex (coupled) behaviour inside the manager. Therefore, I'm trying to work out how to mock the Func<Uri, HwController> ControlFactory so that it returns my setup mock objects so that I can probe the behaviour of the manager.
My system under test creates a concrete instantiation of the HWManager. I realise in a perfect scenario I would test the HwManager and SUT separately, but I'm specifically testing the integration of the two components.
I'd like to configure the autofac to control the delegate factory. If this isn't possible, then I can manually setup the SUT, but then I don't get any value from the autofac helper.
I usually just create a Func that returns my mocked instance e.g.
var controller = mock.Provide<IHWController>();
var manager = new HwManager(something, (uri) => controller);
If the factory is expressing "given a Uri I will provide a controller", the lamda in my example above satisfies that statement.
As an aside, you should express your factories using interfaces, not concrete classes. It makes it a lot harder to unit test when the factories are producing concrete classes instead of interfaces (which can always be mocked) e.g.
// IHwController is the product of the factory instead of HwController
public HwManager(HwType type, Func<Uri, IHwController> ControlFactory)
If anyone gets stuck on this in the future, the key is to create a func that matches the constructor func, customised to provide the appropriate mocks on each invokation (e.g. via an internal counter).
You can then use the mock.Provide() syntax, providing a func that matches the constructor func with your created func above. This will then be invoked correctly allowing you to control the mocks appropriately.

Resolve more than one object with the same class and interface with Simple Injector

I am trying to migrate from Unity to Simple Injector in my new project. It is so much faster than Unity that I have to give it a shot. I have had a few bumps, but nothing I could not work around. But I have hit another one with "Look-up by Key"
I have read this where the creater of simple injector states his belief that you should not need to resolve more than one class per interface.
I must be a poor programmer, because I have done that with Unity (which supports it very well) and want to do it in my current project.
My scenario is that I have an IRepository interface. I have two separate repositories I want to abstract using the IRepository interface. Like this:
container.Register<FirstData>(() => new FirstData());
container.Register<IRepository>(
() => new GenericRepository(container.GetInstance<FirstData>()));
container.Register<SecondEntities>(() => new SecondEntities());
container.Register<IRepository>(
() => new GenericRepository(container.GetInstance<SecondData>()));
IRepository/GenericRepository is a fairly common abstraction, but you can only have one in SimpleInjector
In Unity I could register both of my repositories and then setup my constructor injection to inject the instance that I needed. This was accomplished using a key for the instance. (I did not need to do a Resolve call in my normal code nor add a dependency to Unity outside my setup.)
With simple injector this does not work. But, for better or worse, the owner of Simple Injector thinks this feature is a bad idea.
NOTE: The author's "in app" system looks like it uses a string key for look-up, but it still requires a different class each time (DefaultRequestHandler, OrdersRequestHandler and CustomersRequestHandler). I just have a GenericRepostory which allows me to abstract my repository methods regardless of what I am connected to.
I suppose I could inherit my GenericRepostory for each time I want to instantiate it. Or have it take a random type parameter that I don't need. But that muddles my design, so I am hoping for another way to do it.
So are there any work arounds that don't have me creating bogus types to differentiate between my two IRepository/GenericRepository instances?
We ended up changing our Generic Repository to look like this:
/// The Type parameter has no funcionality within the repository,
/// it is only there to help us differentiate when registering
/// and resolving different repositories with Simple Injector.
public class GenericRepository<TDummyTypeForSimpleInjector> : IRepository
(We added a type parameter to it).
We then created two dummy classes like this (I changed the names of the classes to match my example):
// These are just dummy classes that are used to help
// register and resolve GenericRepositories with Simple Injector.
public class FirstDataSelector { }
public class SecondDataSelector { }
Then I can register them like this:
container.Register<FirstData>(() => new FirstData());
container.Register(() => new GenericRepository<FirstDataSelector>
(container.GetInstance<FirstData>()));
container.Register<SecondEntities>(() => new SecondEntities());
container.Register(() => new GenericRepository<SecondDataSelector>
(container.GetInstance<SecondData>()));
(Note the generic type param on the GenericRepository and that I do not register it as an IRepository. Those two changes are essential to making this work.)
This works fine. And I am then able to use that registration in the constructor injection of my business logic.
container.Register<IFirstBusiness>(() => new FirstBusiness
(container.GetInstance<GenericRepository<FirstDataSelector>>()));
container.Register<ISecondBusiness>(() => new SecondBusiness
(container.GetInstance<GenericRepository<SecondDataSelector>>()));
Since my Business classes take an IRepository it works fine and does not expose the IOC container or the implementation of my repository to the business classes.
I am basically using the Type parameter as Key for lookup. (A hack I know, but I have limited choices.)
It is kind of disappointing to have to add dummy classes to my design, but our team decided that the drawback was worth it rather than abandoning Simple Injector and going back to Unity.
Your own answer is actually quite good, but its unfortunate that you see the generic type parameter as a dummy; you should make it first class citizen of your design:
public interface IRepository<TData> { }
public clss GenericRepository<TData> : IRepository<TData>
{
public GenericRepository(TData data) { }
}
This way you can simply register them as follows:
container.Register<IRepository<FirstData>, GenericRepository<FirstData>>();
container.Register<IRepository<SecondData>, GenericRepository<SecondData>>();
Your business classes can in that case simply depend on the generic IRepository<FirstData> and IRepository<SecondData> and can simply be registered as follows:
container.Register<IFirstBusiness, FirstBusiness>();
container.Register<ISecondBusiness, SecondBusiness>();
Note how the registrations given here don't use any lambdas. Simple Injector can find this out for you. This makes your DI configuration much simpler, more readable, and especially: more maintainable.
This way you make your design very explicit and unambiguous. Your design was ambiguous because you had a single (non-generic) IRepository interface that should be mapped to several implementations. Although this doesn't have to be bad in all cases, in most cases this ambiguity can and should be prevented, because this complicates your code and your configuration.
Further more, since your generic GenericRepository<T> now maps to the generic IRepository<T> we can replace all Register<IRepository<T>, GenericRepository<T>>() registrations with a single line:
// using SimpleInjector.Extensions;
container.RegisterOpenGeneric(typeof(IRepository<>),
typeof(GenericRepository<>);
To take it even one step further, your business classes could perhaps as well benefit from generic typing. Take a look at this article for instance where each business operation gets its own class but all business operations are hidden behind the same generic ICommandHandler<TCommand> abstraction. When you do this, all business classes can be registered with a single call:
container.RegisterManyForOpenGeneric(typeof(ICommandHandler<>),
typeof(ICommandHandler<>).Assembly);
This call searches the supplied assembly for implementations of the ICommandHandler<TCommand> interface and registers each found implementation in the container. You can add new pieces of business logic (use cases) without having to change the configuration. But this is just one of the many advantages of having such abstraction over your business logic. An other great advantage is that it makes adding cross-cutting concerns (such as logging, transaction handling, security, audit trail, caching, you name it) much easier to implement.

DDD Repositories

When creating a repository class, eg. CustomerRepository, should my methods be static?
Or should I first instanciate the CustomerRepository class, and then call the public methods on the instance?
Which approach is best and why?
Thanks
I'd go with an instance simply for unit testing - mocking for example is hard with a static method.
Static methods are death to testability.
I always create an interface which describes the contract for my repository.
Thus, I do not go down the route of static members.
Not only for testability which has already been mentionned, but also because of the fact that my repository needs to have a 'context'.
More specifically, I use NHibernate as an OR/M mapper, and I pass the ISession that should be used to the repository instance. By doing so, multiple repositories can use the same ISession (UnitOfWork), and thus, multiple different types can be persisted within the same transaction.
You should propably create an interface ICustomerRepository, and then create a class CustomerRepository that derives from from that interface.
The reason why is testability.
In tests you can now mock out the concrete instance of CustomerRepositotory with some mock object.
You can also easily replace implementations of this repository, add logging or caching.
As for statics. If you want to use static instance, it's better to use some Dependency Injection tool and set component's lifestyle to singleton. It still would be testable.
Statics are hard to test, but at the same time, statics are eaier to call, everything can be brought down to one method instead of initiating repository and calling its method and closing repository. There are various ways to implement it, we have found following way is the best, because you can not override static methods so in future if you want to inherit and extend functionality, its little bit difficult.
Another approach we have is, we have instance method but we have one static variable.. for example...
CustomerRepository.Repository.GetAll();
and this is how its implemented...
class CustomerRepository{
// Only one static variable
public static CustomerRepository Repository = new CustomerRepository();
// all methods are instance methods..
public IEnumerable GetAll(){
...
}
}

Categories

Resources