I´m having a little bit of trouble sorting a way to manage automatic resolved and manual dependencies in my classes.
Let´s say I have two classes to calculate prices: one calculates how much I will charge for shipping and the other how much I will charge for the entire order. The second uses the first in order to sum the shipping price to the entire order price.
Both classes have a dependency to a third class that I will call ExchangeRate which gives me the exchange rate I should use for price calculation.
So far we have this chain of dependency:
OrderCalculator -> ShippingCalculator -> ExchangeRate
I´m using Ninject to resolve these dependencies and this was working until now. Now I have a requirement that the rate returned by ExchangeRate class will vary upon a parameter that will be provided in the Constructor (because the object won´t work without this, so to make the dependency explicit it´s placed on the constructor) coming from a user input. Because of that I can no longer resolve my dependencies automatically.
Whenever I want to the OrderCalculator or any other classes that depends on ExchangeRate I cannot ask the Ninject container to resolve it to me since I need to provide the parameter in the constructor.
What do u suggest in this case?
Thanks!
EDIT: Let's add some code
This chain of objects is consumed by a WCF service and I'm using Ninject as the DI container.
public class OrderCalculator : IOrderCalculator
{
private IExchangeRate _exchangeRate;
public OrderCalculator(IExchangeRate exchangeRate)
{
_exchangeRate = exchangeRate;
}
public decimal CalculateOrderTotal(Order newOrder)
{
var total = 0m;
foreach(var item in newOrder.Items)
{
total += item.Price * _exchangeRate.GetRate();
}
return total;
}
}
public class ExchangeRate : IExchangeRate
{
private RunTimeClass _runtimeValue;
public ExchangeRate(RunTimeClass runtimeValue)
{
_runtimeValue = runtimeValue;
}
public decimal GetRate()
{
//returns the rate according to _runtimeValue
if(_runtimeValue == 1)
return 15.3m;
else if(_runtimeValue == 2)
return 9.9m
else
return 30m;
}
}
//WCF Service
public decimal GetTotalForOrder(Order newOrder, RunTimeClass runtimeValue)
{
//I would like to pass the runtimeValue when resolving the IOrderCalculator depedency using a dictionary or something
//Something like this ObjectFactory.Resolve(runtimeValue);
IOrderCalculator calculator = ObjectFactory.Resolve();
return calculator.CalculateOrderTotal(newOrder);
}
As always, when you have a partial dependency on a run-time value, the solution is an Abstract Factory.
Something like this should work:
public interface IExchangeRateFactory
{
ExchangeRate GetExchangeRate(object runTimeValue);
}
Now inject an IExchangeRateFactory into your consumers instead of ExchangeRate and use the GetExchangeRate method to convert the run-time value to an ExchangeRate instance.
Obviously you will also need to provide an implementation of IExchangeRateFactory and configure NInject to map the interface to your implementation.
You may find injecting factory delegates or providers to be useful. Both are pretty much impls of Mark's (+1d) answer.
I ended up doing something totally different.
Before I call the ObjectFactory to resolve the dependencies for me I create a new instance of the IExchangeRate using the runTimeValue and tell the IoC/DI container to use it instead of creating a new one. This way the whole chain of objects is preserved and there is no need for factories.
//WCF Service
public decimal GetTotalForOrder(Order newOrder, RunTimeClass runtimeValue)
{
IExchangeRate ex = new ExchangeRate(runtimeValue);
IOrderCalculator calculator = ObjectFactory.With<IExchangeRate>(ex).GetInstance();
return calculator.CalculateOrderTotal(newOrder);
}
But since Ninject doesn't have a way to do this (only Rebind which is not what I want) I changed my container to StructureMap.
Thanks guys for all your help! Really appreciate it!
Move that initialization out of the constructor.
Updated based on the code:
//WCF Service
public decimal GetTotalForOrder(Order newOrder, RunTimeClass runtimeValue)
{
//I would like to pass the runtimeValue when resolving the IOrderCalculator depedency using a dictionary or something
//Something like this ObjectFactory.Resolve(runtimeValue);
IOrderCalculator calculator = ObjectFactory.Resolve();
return calculator.CalculateOrderTotal(newOrder);
}
Notice how this method only wants runtimeValue so that it can pass it to something else? This is happening because object construction and runtime responsibilities are mixed. I think you should be asking for a IOrderCalculator in the constructor for this method.
So this method just becomes:
//WCF Service
public decimal GetTotalForOrder(Order newOrder, IOrderCalculator calculator)
{
return calculator.CalculateOrderTotal(newOrder);
}
Now, when you construct your IOrderCalculator you should pass runtimeValue to it's constructor. It's a bit hard to answer when we do not know what runtimeValue is or where it comes from.
Related
I found myself struggling with some patterns when trying to implement a DAL for my application.
Some context concerning my knowlege:
C# is quite new for me and some issues might be due to some lacking knowledge (in this case I would say especially with generics)
Using Dependency injection is also something new for me, although I think I understand it properly now.
The factory pattern is also new for me. I get it and I've used it with some libraries, but this is the first time I really implement it.
What I want to achieve :
I'm coding a DAL and to use it I need to retrieve a DatabaseReader object that depends on the object I want to link with my database. I want to be able to construct those objects dynamically while taking advantages of Dependency injection.
A good way to do this according to my research is to create a factory that would be injected into my classes which would be able then to Instantiate them.
I got some good tips from this article: (How not to do dependency injection ) which has an example with a factory registration. But I haven't been successful properly understanding it and implementing it using the SimpleContainer of caliburn micro.
My code so far:
I'm implementing the DAL as shown in this article (Data Access Layer using the Template Pattern and Generics )
I will take for example a Mapper that I want a factory for (in reality I don't want to retreive it directly but it is simpler for the concept).
The base generic class :
abstract class MapperBase<T>
{
protected abstract T Map(IDataRecord record);
public Collection<T> MapAll(IDataReader reader){
...
}
}
a concrete mapper:
class LincolnTelemetryMapper : MapperBase<LincolnTelemetryModel>
{
protected override LincolnTelemetryModel Map(IDataRecord record)
{
try
{
LincolnTelemetryModel telemetry = new LincolnTelemetryModel();
telemetry.Timestamp = (DBNull.Value == record["measureDate"]) ?
null : (DateTime)record["measureDate"];
telemetry.Voltage = (DBNull.Value == record["voltage"]) ?
null : decimal.ToDouble((decimal)record["voltage"]);
...
} catch { ... }
}
}
And then the factory code (not in a working state) that I'm trying to implement and register in my IoC container:
interface IMapperFactory<T>
{
bool AppliesTo(Type type);
MapperBase<T> CreateMapper(object mappedObject);
}
class MapperFactory<T> : IMapperFactory<T>
{
public bool AppliesTo(Type type)
{
return typeof(T).Equals(type);
}
public MapperBase<T> CreateMapper(object mappedObject)
{
switch (mappedObject)
{
case LincolnTelemetryModel:
LincolnTelemetryMapper lincmapper = new LincolnTelemetryMapper();
MapperBase<LincolnTelemetryModel> telemetrymapper = lincmapper;
return (MapperBase<T>)telemetrymapper;
default:
return null;
}
}
}
My questions:
In the factory above, The mapper cannot be returned: The type MapperBase cannot be casted in MapperBase. There is probably something I'm not understanding well with the c# generics. can someone point me to the real issue here ?
Any way to do a generic factory that can work with any object without having to explicitly create each mapper. Unlike the example below, by registering something like MapperBase instead of the concrete implementation.
Some test code from the bootstrapper that I'm not satisfied with... and smell like misunderstanding something.
MapperFactory<LincolnTelemetryModel> lincolnTelemetryMapperFact = new MapperFactory<LincolnTelemetryModel>();
//register factory ?
container.Instance<MapperFactory<LincolnTelemetryModel>>(lincolnTelemetryMapperFact);
//or a mapped object ?
LincolnTelemetryModel testmodel = new LincolnTelemetryModel(); //in userClass
LincolnTelemetryMapper factoredMapper = lincolnTelemetryMapperFact.CreateMapper(testmodel);
container.RegisterPerRequest(LincolnTelemetryMapper, "key", factoredMapper);
edit:
I want to precise that I know the code above is useless but it serves as a step to implement something generic.
I could of course directly register the mappers by type and be done with it. the goal is to generalize to only one factory for all Mappers. With the model object as an argument.
Thank you for your help,
I have a (growing) list of Data-Generators. The generator that I need is created by a factory class. The generators all implement a common Interface, which includes among other things a static string name.
What I would like to do: Call the factory.Create method with a string parameter for the above mentioned name. The create method finds the generator with this name and returns a new instance of said generator.
Bonus in my opinion of this way to do it: I only have to add new generator classes without having to edit the factory.
Question:
Is this a good way to handle this problem?
How can I find all generators? Reflection over every implementation of the interface/every member of the namespace (unique for the generators + their interface)?
Is it correct to call this way of working a factory, or is this some different pattern?
In the end I would call the factory like this (simplified):
//Caller
public DataModel GetData2()
{
var generator = new DataFactory().Create("Gen.2");
return generator.GetData();
}
//Factory
public class DataFactory
{
public AbstractDataGenerator Create(string type)
{
//Here the magic happens to find all implementations of IDataGenerator
var allGenerators = GetImplementations();
var generator = allGenerators.FirstOrDefault(f => f.name == type);
if (generator != null)
return (AbstractDataGenerator)Activator.CreateInstance(generator);
else
return null;
}
}
//Interface
public abstract class AbstractDataGenerator
{
public static string name;
public abstract DataModel GetData();
}
//Data-Generators
public class DataGen1 : AbstractDataGenerator
{
public static string name = "Gen.1";
public DataModel GetData()
{
return new DataModel("1");
}
}
public class DataGen2 : AbstractDataGenerator
{
public static string name = "Gen.2";
public DataModel GetData()
{
return new DataModel("2");
}
}
Should the magic GetImplementations() in the factory be done via Reflection or somehow different? Should I use a completely different approach?
Since answers refer to IoC and DI: This project uses NInject already, so it would be available.
Switched from interface to abstract class.
Is this a good way to handle this problem?
Having a factory to get an instance of the logic class you need by some key - I believe it is a good way. It is a pattern that I use a lot myself. About the way you have your key - I'd prefer to not have it as a static member (regardless to the fact that interfaces can't have static members) but just as a property and to add a base class to the IDataGenerator. That base class will have a constructor that will get the name - That way each new DataGenerator you create will have to set it and you wont forget.
About having the name as a string - I personally prefer having it "strongly typed". What I mean is that if I pass Gen . 2 instead of Gen.2 with strings I will discover this problem only in runtime. Possible other ways (if you want, because a simple string is fine too - a matter of taste):
Replace strings with an enum
Have a static class with static readonly strings for all your values - then in your code use those values. You get the benifits of the intellisense and of not getting the string wrong but better than enum - you can just still pass strings that are not in the "list" so you can add new ones as add-ons.
Have a RequestGenerator object, with each Generator being IDataGenerator<TGeneratorRequest>. This might be an overkill but if you have also extra information you need for the creating of a DataGenerator which differs between them then consider it .
How can I find all generators? Reflection over every implementation of the interface/every member of the namespace (unique for the generators + their interface)?
Yes, reflection can be a good way to do so. However, I would suggest to read into Dependency Injection and IoC Containers like Castle Windsor for example. There are things out there that already implement it for you, so why to re-invent the wheel :)
DI is a life changer concept in my opinion
Is it correct to call this way of working a factory, or is this some different pattern?
Yap. It is a Factory
Should the magic GetImplementations() in the factory be done via Reflection or somehow different?
See answer for question 2
This is where constructor injection can REALLY shine. Look into dependency injection tools and employ one! It also checks your "Bonus" request.
Here's what your factory might look like with constructor injection:
public class DataFactory
{
private Dictionary<string, IDataGenerator> generators;
public DataFactory(IDataGenerator[] generatorReferences)
{
this.generators = generatorReferences
.ToDictionary(k => k.name, v => v);
}
public IDataGenerator Create(string type)
{
IDataGenerator generator = null;
this.generators.TryGetValue(type, out generator);
return generator;
}
}
Most DI software has the capability to automatically scan assemblies for implementations of a certain type (e.g. IDataGenerator) and register those with itself, when it constructs an instance of your DataFactory it'll automatically include them.
I am in the process of refactoring a rather large portion of spaghetti code. In a nutshell it is a big "God-like" class that branches into two different processes depending in some condition. Both processes are lengthy and have lots of duplicated code.
So my first effort has been to extract those two processes into their own classes and putting the common code in a parent they both inherit from.
It looks something like this:
public class ExportProcess
{
public ExportClass(IExportDataProvider dataProvider, IExporterFactory exporterFactory)
{
_dataProvider = dataProvider;
_exporterFactory = exporterFactory;
}
public void DoExport(SomeDataStructure someDataStructure)
{
_dataProvider.Load(someDataStructure.Id);
var exporter = _exporterFactory.Create(_dataProvider, someDataStructure);
exporter.Export();
}
}
I am an avid reader of Mark Seemann's blog and in this entry he explains that this code has a temporal coupling smell since it is necessary to call the Load method on the data provider before it is in a usable state.
Based on that, and since the object is being injected to the ones returned by the factory anyway, I am thinking of changing the factory to do this:
public IExporter Create(IExportDataProvider dataProvider, SomeDataStructure someDataStructure)
{
dataProvider.Load(someDataStructure.Id);
if(dataProvider.IsNewExport)
{
return new NewExportExporter(dataProvider, someDataStructure);
}
return new UpdateExportExporter(dataProvider, someDataStructure);
}
Because of the name "DataProvider" you probably guessed that the Load method is actually doing a database access.
Something tells me an object doing a database access inside the create method of an abstract factory is not a good design.
Are there any guidelines, best practices or something that say this is effectively a bad idea?
Thanks for your help.
Typically, a factory is used to resolve concrete types of a requested interface or abstract type, so you can decouple consumers from implementation. So usually a factory is just going to discover or specify the concrete type, help resolve dependencies, and instantiate the concrete type and return it. However, there's no hard or fast rule as to what it can or can't do, but it is sensible to give it enough access to only to resources that it needs to resolve and instantiate concrete types.
Another good use of a factory is to hide from consumers types dependencies that are not relevant to the consumer. For example, it seems IExportDataProvider is only relevant internally, and can be abstracted away from consumers (such as ExportProcess).
One code smell in your example, however, is how IExportDataProvider is used. The way it currently seems to work, you get an instance of it once, but it's possible to change its state in subsequent usages (by calling Load). This can lead to issues with concurrency and corrupted state. Since I don't know what that type does or how it's actually used by your IExporter, it's hard to make a recommendation. In my example below, I make an adjustment so that we can assume that the provider is stateless, and instead Load returns some sort of state object that the factory can use to resolve the concrete type of exporter, and then provide data to it. You can adjust that as you see fit. On the other hand, if the provider has to be stateful, you'll want to create an IExportDataProviderFactory, use it in your exporter factory, and create a new instance of the provider from the factory for each call to exporter factory's Create.
public interface IExporterFactory
{
IExporter Create(SomeDataStructure someData);
}
public class MyConcreteExporterFactory : IExporterFactory
{
public MyConcreteExporterFactory(IExportDataProvider provider)
{
if (provider == null) throw new ArgumentNullException();
Provider = provider;
}
public IExportDataProvider Provider { get; private set; }
public IExporter Create(SomeDataStructure someData)
{
var providerData = Provider.Load(someData.Id);
// do whatever. for example...
return providerData.IsNewExport ? new NewExportExporter(providerData, someData) : new UpdateExportExporter(providerData, someData);
}
}
And then consume:
public class ExportProcess
{
public ExportProcess(IExporterFactory exporterFactory)
{
if (exporterFactory == null) throw new ArgumentNullException();
_exporterFactory = factory;
}
private IExporterFactory _exporterFactory;
public void DoExport(SomeDataStructure someData)
{
var exporter = _exporterFactory.Create(someData);
// etc.
}
}
I have a service layer that retrieves a DTO from a repository. Depending on a property in that DTO I need to use one of two strategies to perform calculations on the DTO. I have created a factory to return the appropriate strategy and I'm using a DI container (Munq) to instantiate the object.
public class CalculationFactory
{
private readonly IDependencyResolver _resolver;
public CalculationFactory(IDependencyResolver resolver)
{
ThrowIfNullArgument(resolver, "resolver", typeof(IDependencyResolver));
_resolver = resolver;
}
public static ICalculation CreateCalculator(int serviceType)
{
switch (serviceType)
{
case 1: return _resolver.Resolve<ICalculation>("Type1");
case 2: return _resolver.Resolve<ICalculation>("Type2");
default: return _resolver.Resolve<ICalculation>("InvalidType");
}
}
}
This requires me to pass in the dependency resolver when I instantiate the factory so that it can be used to resolve/instantiate the appropriate calculation to use. Is this the correct approach? If I want to add a new type of calculation then I would need to update the factory CreateCalculator method and register the new type.
Update (long)
I'm not really getting traction on the suggestions I'm afraid. I've gone back to my copy of Mark's DI in .Net and specifically chapter 6 on refactorings. So I have a class MeterReadings and I need to calculate a charge using one of two calculations based on a runtime value. I add an abstract factory to the mix but in my concrete factory I still need to new up the appropriate calculation. I feel like I'm missing the point here:
public enum ServiceType
{
Actuals = 1, CopyBlock,
}
public interface IChargeCalculator
{
decimal CalculateCharge();
}
public interface IChargeCalculatorFactory
{
IChargeCalculator CreateChargeCalculator(ServiceType serviceType);
}
public class MeterReading
{
private readonly IChargeCalculatorFactory chargeCalculatorFactory;
public MeterReading(IChargeCalculatorFactory chargeCalculatorFactory)
{
if (chargeCalculatorFactory == null)
throw new ArgumentNullException("chargeCalculatorFactory");
this.chargeCalculatorFactory = chargeCalculatorFactory;
}
}
public class ConcreteChargeCalculatorFactory : IChargeCalculatorFactory
{
public IChargeCalculator CreateChargeCalculator(ServiceType serviceType)
{
switch (serviceType)
{
case ServiceType.Actuals : return new ActualsChargeCalculator();
default: return new CopyBlockChargeCalculator();
}
}
}
But in my container I can register the different calculators and if I pass in the container as the concrete factory I get something like the following (not tested) which frankly looks fairly reasonable to me. Any feedback/clarification would be welcome.
Container.Register<IChargeCalculator>("Actuals",
c => new ActualsChargeCalculator());
Container.Register<IChargeCalculator>("CopyBlock",
c => new CopyBlockChargeCalculator());
...
public enum ServiceType
{
Actuals = 1, CopyBlock,
}
public interface IChargeCalculator
{
decimal CalculateCharge();
}
public class MeterReading
{
private readonly IDependencyResolver chargeCalculatorFactory;
private ServiceType serviceType;
public MeterReading(IDependencyResolver chargeCalculatorFactory)
{
if (chargeCalculatorFactory == null)
throw new ArgumentNullException("chargeCalculatorFactory");
this.chargeCalculatorFactory = chargeCalculatorFactory;
}
public decimal Charge
{
get
{
return chargeCalculatorFactory.Resolve<IChargeCalculator>(serviceType.ToString());
}
}
}
Yes, I would say you are doing it in a proper way.
Though you write that you need to "pass in the dependency resolver ", is there a reason that you can't have the factory class injected into the class where it is needed? Then the factorys dependency on the dependency resolver should be resolved by the dependency resolver itself (to itself).
I hope that sentence made sense.
I have tried to come up with a "cleaner" solution, but have not found any yet. A solution similar to what is suggested in the question (which is not exactly the same) Dessus links is certainly possible, but I really see that as just moving the same code to another place. Remo also writes that it could be done in a factory class instead of a factory method.
It's a bit like deciding between writing a lampda or a helper class. It mostly comes down to readabilty, and for me a factory method is just to big, and having it in a module initializer or bootstrapper seams to disorganized.
BTW I can recommend Ninject, it is a really good, clean DI. Plus it's documentation uses Ninja examples ;)
I believe this question has been answered here, where it is suggested you use meta data against your bindings and create bindings for each implementation. You then use a binding to pull the meta data to choose which binding to use: Ninject conditional binding based on property value . Possibly this may or may not be possible with Munq? Not sure.
The person (Remo) who answered that question is one of the architects of ninject, and is very knowledgeable. I believe that his answer should hold alot of weight. (I am a basing this of being a subscriber to the ninject mailing list, and seeing him answer about half of all the questions).
Is this a good pattern? It has a code smell to me with having a factory class aware of the IUnityContainer...
My basic need was to resolve an ICalculationRuleProcess at runtime depending on an Id of a class. It could be based on something other than the Id, I am aware of that... basically I have a known set of Ids that I need to deal with because I bootstrapped the records into the database manually and there is no way to edit the records. With each Id I have a related class. I also have a varying number of constructor parameters within each class that implements the ICalculationRuleProcess, so using an IoC container is extremely helpful versus some crazy switch statement and variable constructor aguments using Activator.CreateInstance
Here is what I did:
Registered the IUnityContainer instance within the container itself. I wasnt sure if this was even possible, but it worked.
Registered all of the ICalculationRuleProcess classes with a unique identifier within the registration (basically just the Id.ToString() of each possible DistributionRule)
Created a factory to determine the correct ICalculationRuleProcess, and had it use the IoC container to figure out the correct class to load.
Registered the factory class (ICalculationRuleProcessFactory) to the IoC container
Wherever the ICalculationRuleProcess needed to be used, I had the class take an ICalculationRuleProcessFactory in its constructor and have it call the Create method to figure out which ICalculationRuleProcess to use.
The code for the factory is here:
public interface ICalculationRuleProcessFactory
{
ICalculationRuleProcess Create( DistributionRule distributionRule );
}
public class CalculationRuleProcessFactory : ICalculationRuleProcessFactory
{
private readonly IBatchStatusWriter _batchStatusWriter;
private readonly IUnityContainer _iocContainer;
public CalculationRuleProcessFactory(
IUnityContainer iocContainer,
IBatchStatusWriter batchStatusWriter )
{
_batchStatusWriter = batchStatusWriter;
_iocContainer = iocContainer;
}
public ICalculationRuleProcess Create( DistributionRule distributionRule )
{
_batchStatusWriter.WriteBatchStatusMessage(
string.Format( "Applying {0} Rule", distributionRule.Descr ) );
return _iocContainer.Resolve<ICalculationRuleProcess>(
distributionRule.Id.ToString() );
}
}
This seems okay to me, given the constraints you described. The most important thing is that all of your rules implement ICalculationRuleProcess and that all consumers of those rules only know about that interface.
It isn't inherently bad that your factory takes the container dependency, especially as an interface. Consider that if you ever had to change container implementations, you could create an IUnityContainer implementation that doesn't use Unity at all (just forward all the members of the interface to their corresponding methods in the replacement container).
If it really bothers you, you can add yet another layer of indirection by creating an agnostic IoC interface with the requisite Register, Resolve, etc. methods and create an implementation that forwards these to Unity.
There is another way you can achieve this without factory taking dependency on IUnityContainer, which is not inherently bad in and of itself. This is just a different way to think about the problem.
The flow is as follows:
Register all different instances of ICalculationRuleProcess.
Get all registered ICalculationRuleProcess and create a creation lambda for each one.
Register ICalculationRuleProcessFactory with a list of ICalculationRuleProcess creation lambdas.
In ICalculationRuleProcessFactory.Create return the right process.
Now the tricky part of this is to preserve the Ids that the registrations were made under. Once solution is to simply keep the Id on the ICalculationProcess interface, but it might not semantically belong there. This is where this solution slips into ugly (which is more of a case of missing functionality in Unity). But, with an extension method and a small extra type, it looks nice when it's run.
So what we do here is create an extension method that returns all registrations with their names.
public class Registration<T> where T : class {
public string Name { get; set; }
public Func<T> CreateLambda { get; set; }
public override bool Equals(object obj) {
var other = obj as Registration<T>;
if(other == null) {
return false;
}
return this.Name == other.Name && this.CreateLambda == other.CreateLambda;
}
public override int GetHashCode() {
int hash = 17;
hash = hash * 23 + (Name != null ? Name.GetHashCode() : string.Empty.GetHashCode());
hash = hash * 23 + (CreateLambda != null ? CreateLambda.GetHashCode() : 0);
return hash;
}
}
public static class UnityExtensions {
public static IEnumerable<Registration<T>> ResolveWithName<T>(this UnityContainer container) where T : class {
return container.Registrations
.Where(r => r.RegisteredType == typeof(T))
.Select(r => new Registration<T> { Name = r.Name, CreateLambda = ()=>container.Resolve<T>(r.Name) });
}
}
public class CalculationRuleProcessFactory : ICalculationRuleProcessFactory
{
private readonly IBatchStatusWriter _batchStatusWriter;
private readonly IEnumerable<Registration<ICalculationRuleProcess>> _Registrations;
public CalculationRuleProcessFactory(
IEnumerable<Registration<ICalculationRuleProcess>> registrations,
IBatchStatusWriter batchStatusWriter )
{
_batchStatusWriter = batchStatusWriter;
_Registrations= registrations;
}
public ICalculationRuleProcess Create( DistributionRule distributionRule )
{
_batchStatusWriter.WriteBatchStatusMessage(
string.Format( "Applying {0} Rule", distributionRule.Descr ) );
//will crash if registration is not present
return _Registrations
.FirstOrDefault(r=>r.Name == distributionRule.Id.ToString())
.CreateLambda();
}
}
//Registrations
var registrations = container.ResolveWithName<ICalculationRuleProcess>(container);
container.RegisterInstance<IEnumerable<Registration<ICalculationRuleProcess>>>(registrations);
After I wrote this I realised that this is more creative lambda douchebaggery than a architecturally pretty solution. But in any case, feel free to get ideas out of it.
Hey Rob, I'm intending to use essentially the same pattern. I've got multiple types of shopping cart item that need to be associated with their own specific set of validator instances of varying class.
I think there is a smell about this pattern and its not that the factory has a reference to the IoC container, its that typically, an IoC container is configured in the application root which is typically the UI layer. If a crazy custom factory was created just to handle these associations then possibly it should be in the domain.
In short, these associations are possibly not part of the overall program structure that's set up before the application runs and so shouldn't be defined in the application root.