This class injects all dependencies in the constructor, but only one of the dependencies are used at a time. Is this considered bad design?
public class OrderPayment
{
ICreditCardPayment _ccPayment;
ICashPayment _cashPayment;
public OrderPayment(ICreditCardPayment ccPayment, ICashPayment cashPayment)
{
_ccPayment = ccPayment;
_cashPayment = cashPayment;
}
private void PrepareOrder(Order order)
{
// Do stuff with the order
}
public PaymentResult PayByCreditCard(Order order)
{
PrepareOrder(order);
return _ccPayment.Pay(order);
}
public PaymentResult PayByCreditCard(Order order)
{
PrepareOrder(order);
return _cashPayment.Pay(order);
}
}
An alternative is this:
public class OrderPayment
{
private void PrepareOrder(Order order)
{
// Do stuff with the order
}
public PaymentResult PayByCreditCard(Order order, ICreditCardPayment ccPayment)
{
PrepareOrder(order);
return ccPayment.Pay(order);
}
public PaymentResult PayByCreditCard(Order order, ICashPayment cashPayment)
{
PrepareOrder(order);
return cashPayment.Pay(order);
}
}
This one complicates the function call somewhat. Would you use the first, cleaner looking one, even though not every constructor parameter is used? Considering a DI framework has to instantiate potentially heavy classes even though they may not all be used, I'm not sure how good this is.
So which one would you use? Or maybe a different implementation?
I would refactor or extract a common interface from ICashPayment and ICreditCardPayment. Your code sample indicates your methods are both invoking xPayment.Pay, which looks like a good candidate for your common interface method.
public interface IPayment
{
PaymentResult Pay(Order order);
}
Your more specialized interfaces can inherit from and build upon it.
In general, I would avoid having constructors (or any method) accept arguments that go unused, or if one argument is used, the other is not. That's normally an indication that you are either not operating at the proper level of abstraction, or that your class/method has too many responsibilities.
You need an operation that requires all of the following:
the payment method
the amount being paid
the order that is being paid for
What processing needs to be done prior to payment, based on the order, and amount being paid
You are trying to define some order of operation independent of what is being performed in the operation. Dependency injection can be used at the method level too.
you need a method like this one:
public PaymentResult Pay(Amount amount, Order order, IOrderService orderService,
IPaymentService paymentService) {
var updatedOrder = orderService.Process(order); // don't alter the original in
// case you need to roll back
var result = paymentService.Pay(amount, updatedOrder);
return result; // this result should include the updated order, so that the system
// can determine what to do upon successful payment
}
Related
What is a good (object oriented) way of setting a property of a class which implements an interface, when that property doesn't always exist in all classes that implement that same interface?
e.g.
Let's say I have an interface
public interface IDataRepository {
public DataStructure GetData(); // DataStructure is an arbitrary class, doesn't matter for this example
}
Now I also have two classes that inherit from this
public class DatabaseRepository : IDataRepository {
public DataStructure GetData()
{
// get data from database
}
}
and
public class FileRepository : IDataRepository {
public string WorkingFolder { get; set; }
public DataStructure GetData() {
// get data from files
}
}
Now my client method doesn't necessarily know what the repository is but here's what I want to do...
private DataStructure ReadData(IDataRepository repository)
{
repository.WorkingFolder = #"C:\Data"; // What is the best way of doing this?
return repository.GetData();
}
obviously the above code won't work and I could do...
if (repository is FileRepository) {
((FileRepository)repository).WorkingFolder = #"C:\Data";
}
or add WorkingFolder as a property of the interface (and therefore all the classes that implement it) even though in most cases it's irrelevant.
but both of these (esp. the first one) seem very inelegant and not very object oriented. What is the oop way of doing this kind of thing?
Edit
The obvious question is if the method doesn't know what repository is, how can it know the correct value for WorkingFolder... But the above is an over-simplification of what I'm trying to do, so let's just say it can find out...
Apparently your ReadData method can't actually accept any type of repository. It is only able to handle a FileRepository. That's what it expects, and that's what it needs to do its job. Given that, that's what it should actually accept as its parameter, rather than an interface that doesn't actually provide a contract that is sufficient for it to do its job.
The entire point of having an interface is so that anyone using that interface can use it without caring what the implementation is. So if you do want to use the interface you need to include enough information in the interface's definition such that it provides every operation that anyone using the interface needs, otherwise you're better off just not using it at all (at least for that specific operation).
As for the specific example given, you should probably just be providing an already configured repository, that has whatever values it needs in order to allow this method to do its work, as a parameter. It doesn't make sense for a method that's reading a value from an arbitrary repository to be configuring that repository at all. That is, if it really is reading something from an arbitrary repository.
As others have said in the comments, you should initialise these properties in the constructor. This is where you know what type you're creating, so you also know what arguments its constructor requires / can set those there.
Once you've initialised the object, you can just pass it around / have anything using that class operate against its interface.
Example:
public void Main(string[] args)
{
var myRepo = new FileRepository(args[0]); //Here's where we set the working directory
var myThing = new Thing();
var data = myThing.ReadData(myRepo);// of course, the current implementation means you could just call `myRepo.GetData()` directly, since ReadData just passes out the same response; but presumably that method adds some additional value..
Console.WriteLine(data.ToString());
}
Supporting Code
public class DatabaseRepository : IDataRepository {
DbConnection connection; //you may want a connection string or something else; going with this type just to illustrate that this constructor uses a different type to the FileRepo's
public DatabaseRepository(DbConnection connection)
{
this.connection = connection;
}
public DataStructure GetData()
{
// get data from database
}
}
public class FileRepository : IDataRepository {
public string WorkingFolder { get; set; } //Do you need set? Generally best to keep it constant after initialisation unless there's good reason to change it
public FileRepository (string workingFolder)
{
this.WorkingFolder = workingFolder;
}
public DataStructure GetData() {
// get data from files
}
}
How do I call the code that creates the class
i.e. maybe you've implemented a really basic factory pattern like so, and want to know how to provide arguments:
public class DataRepositoryFactory
{
Type baseType = typeof(IDataRepository);
IDictionary<string, Type> typeMap = new Dictionary<string, Type>() {
{"File", typeof(FileRepository) }
,{"Db", typeof(DatabaseRepository) }
}
public void RegisterType(string typeName, Type type)
{
if (!baseType.IsAssignableFrom(type)) throw new ArgumentException(nameof(type));
typeMap.Add(typeName, type);
}
public IDataRepository GetDataRepository(string typeName)
{
return (IDataRepository)Activator.CreateInstance(typeMap[typeName]);
}
}
(For a more complex example of a factory, see https://web.archive.org/web/20140414013728/http://tranxcoder.wordpress.com/2008/07/11/a-generic-factory-in-c).
I.e. in this scenario, when you call the factory you know what type you want, but you're only giving it a string to name/identify that class. You could add a params object[] args to your GetDataRepository method, allowing you to call it like so:
var myRepo = myDataRepositoryFactory.GetDataRepository("File", "c:\somewhere\something.dat");
That's a good approach / is actually what's used on the linked example above. However, it means that your call to this code differs for different types; since if we use variables instead of hardcoded values as in the above example we can't simply do the below, since myRepoType could be set to "Db", whilst "myFilePath" would be a string:
var myRepo = myDataRepositoryFactory.GetDataRepository(myRepoType, myFilePath);
That's fixable by calling:
var myRepo = myDataRepositoryFactory.GetDataRepository(myRepoType, myArgs);
i.e. where myArgs is an object[], giving all of the values required in the desired order to initialise the type. The piece to populate object[] with the required values could then take place at the same point at which you decided you wanted the type to be a file repo vs database repo. However, this approach isn't that clean / casting to and from objects stops you from getting help from the compiler.
So how do I improve things?
There are a few options. One is to replace the need to use object[] by instead creating a type to hold your arguments. e.g.
public interface IDataRepositoryConfiguration
{
//nothing required; this is just so we've got a common base class
}
public class FileRepositoryConfiguration: IDataRepositoryConfiguration
{
public string WorkingFolder {get;set;}
}
public class FileRepository : IDataRepository {
public FileRepository (IDataRepositoryConfiguration configuration)
{
var config = configuration as FileRepositoryConfiguration;
if (config == null) throw new ArgumentException(nameof(configuration)); //improve by having different errors for null config vs config of unsupported type
this.WorkingFolder = config.WorkingFolder;
}
//...
}
This still has some issues; i.e. we may pass a DatabaseRepositoryConfiguration as our IRepositoryConfiguration when creating a FileRepository, in which case we'd get the AgumentNullException at runtime; but this does avoid issues should parameters change order, and makes it less of a headache to code / debug.
Could it be further improved?
Dependency Injection offers one solution. This could be used along the lines of the code below (i.e. you create instances of each of your classes, providing the required arguments, and give each instance a name, so that you can later fetch that instantiation. Exactly what that code looks like would depend on the dependency injection library you used:
//setting up your repositories
var container = new Container();
container.Configure(config =>
{
// Register stuff in container, using the StructureMap APIs...
config.For<IDataRepository>().Add(new FileRepository("\\server\share\customers")).Named("customers");
config.For<IDataRepository>().Add(new FileRepository("\\server\share\invoices")).Named("invoices");
config.For<IDataRepository>().Add(new DatabaseRepository(new DbConnection(configurationString))).Named("persist");
config.For<IDataRepository>().Use("persist"); // Optionally set a default
config.Populate(services);
});
//then later when you need to use it...
public DataStructure ImportCustomers(IContainer container)
{
var customerRepo = container.GetInstance<IDataRepository>("customers");
return customerRepo.GetData();
}
I'm sure there are many other approaches, and exactly what approach to use depends on how your program will operate. Hopefully the above is enough to get you past your current problem; but if you find you're still struggling please post a new question with more detail / saying where you're still having issues having considered these points.
If possible, I'd just put the value for that property in the constructor or create a subinterface, like others suggested.
If it's not possible, C# 7.X (don't remember the exact minor version) has a nice code structure for conditional casting:
IDataRepository repo = new FileRepository();
if (repo is FileRepository fileRepo)
{
fileRepo.WorkingFolder = "some dir";
}
However in your case, you should probably rethink your architecture and always pass (or even better always create) a repository object which is ready to be used.
a) Put it into the Inferface definitions. Deal with any "NotImplemented" Exceptions. You always have to expect those with Interfaces anyway.
For example, IEnumerable has a Reset() function. But in most cases it is not implemented. It is not even supposed to be implemented in most cases. Afaik it is only there for Backwards Compatabilty with some old COM stuff.
b) make a sub-interface just for the property
c) Verify the Interface is properly implemented via is checks (throw exceptions thows if nessesary, like Array.Sort will throw a InvalidOperation one), generic constraints, proper argument types and the like.
I'm trying to design a class hierarchy in C# to properly model my application model.
The problem is I'm not sure which is the right way to do it.
Let's say I have an Order class which is supposed to be the base (abstract) class for all order types and the reference type I'm working with when using orders. The order class has only a single 'important' method: let's call it order.PlaceOrder(), but there are multiple (orthogonal) requirements that an order might have to do (or not do): log the placing of the order, place the order asynchronously (PlaceOrder method returns immediately) and others.
Now, I want to make actual concrete classes which can support any number of these requirements. For example:
class GoogleOrder : LoggedOrder, AsyncOrder, etc
class AppleOrder: AsyncOrder
class MicrosoftOrder : Order
The question is: if I want to create such a class by deriving from all the "strategies", then they all (but one) have to be interfaces, whereas I wish to inherit actual implementation and avoid copy/pasting of code, and I'm not sure how to do it.
I come from a C++ background, where I could just derive from multiple base classes (or possibly use a policy based design, like Andrei Alexandrescu describes in his book), but in C# I'm not sure how to do it, even though this seems like a very general question, one which I should know by now.
Any help is greatly appreciated!
It seems like your design calls for "Decorator pattern", Decorator pattern gives flexibility to add responsibilities/roles dynamically and with different combinations however you like instead of using inheritance.
here are example on how to implement decorator:
http://alagesann.com/2013/08/16/decorator-pattern-made-easy/
http://en.wikipedia.org/wiki/Decorator_pattern
hope that helps.
here is the sample code for your scenario. see if it helps.
public abstract class Order
{
public abstract void PlaceOrder(); // log the placeing of the ordr, place the order asynchronously
}
public class MicrosoftOrder : Order // default order
{
public void PlaceOrder()
{
// default implementation for placing order.
}
}
public class AppleOrder : Order // for asycn functionalities.
{
private Order order;
public AppleOrder(Order order)
{
this.order = order;
}
public void PlaceOrder()
{
// Implement async functionalities.
// you can also call default order as
// order.PlaceOrder();
}
}
public class GoogleOrder : Order // logged order
{
private Order order;
public GoogleOrder(Order order)
{
this.order = order;
}
public void PlaceOrder()
{
// Implement logged order
// you can also call default order as
// order.PlaceOrder();
}
}
class Program
{
static void Main(string[] args)
{
Order order = new MicrosoftOrder();
order.PlaceOrder(); // Default Order;
Order orderWithAsync = new AppleOrder(order);
orderWithAsync.PlaceOrder(); // Place order with asycn
Order orderWithAsyncAndlogging = new GoogleOrder(orderWithAsync);
orderWithAsyncAndlogging.PlaceOrder(); // order with asynch and logging.
}
}
I'm trying to make an app I'm designing more generic and implement the command pattern into it to use manager classes to invoke methods exposed by interfaces.
I have several classes with the GetItem() and GetList() methods in them, some are overloaded. They accept different parameters as I was trying to use dependency injection, and they return different types. Here are a couple of examples:
class DatastoreHelper
{
public Datastore GetItem(string DatastoreName)
{
// return new Datastore(); from somewhere
}
public Datastore GetItem(int DatastoreID)
{
// return new Datastore(); from somewhere
}
public List<Datastore> GetList()
{
// return List<Datastore>(); from somewhere
}
public List<Datastore> GetList(HostSystem myHostSystem)
{
// return List<Datastore>(); from somewhere
}
}
class HostSystemHelper
{
public HostSystem GetItem(int HostSystemID)
{
// return new HostSystem(); from somewhere
}
public List<HostSystem> GetList(string ClusterName)
{
//return new List<HostSystem>(); from somewhere
}
}
I'm trying to figure out if I could use a generic interface for these two methods, and a manager class which would effectively be the controller. Doing this would increase the reuse ability of my manager class.
interface IGetObjects
{
public object GetItem();
public object GetList();
}
class GetObjectsManager
{
private IGetObjects mGetObject;
public GetObjectsManager(IGetObjects GetObject)
{
this.mGetObject = GetObject;
}
public object GetItem()
{
return this.mGetObject.GetItem();
}
public object GetList()
{
return this.GetList();
}
}
I know I'd have to ditch passing in the parameters to the methods themselves and use class properties instead, but I'd lose the dependency injection. I know I'd have to cast the return objects at the calling code into what they're supposed to be. So my helper classes would then look like this:
class DatastoreHelper
{
public string DatastoreName { get; set; }
public string DatastoreID { get; set; }
public object GetItem()
{
// return new Datastore(); from somewhere
}
public List<object> GetList()
{
// return List<Datastore>(); from somewhere
}
}
class HostSystemHelper
{
public int HostSystemID { get; set; }
public string ClusterName {get; set;}
public object GetItem()
{
// return new HostSystem(); from somewhere
}
public List<object> GetList()
{
//return new List<HostSystem>(); from somewhere
}
}
But is the above a good idea or am I trying to fit a pattern in somewhere it doesn't belong?
EDIT: I've added some more overloaded methods to illustrate that my classes are complex and contain many methods, some overloaded many times according to different input params.
If I understand the concept correctly, a design like this is a really bad idea:
class DatastoreHelper
{
public string DatastoreName { get; set; }
public string DatastoreID { get; set; }
public object GetItem()
{
// return new Datastore(); from somewhere
}
public List<object> GetList()
{
// return List<Datastore>(); from somewhere
}
}
The reason is that getting results would now be a two-step process: first setting properties, then calling a method. This presents a whole array of problems:
Unintuitive (everyone is used to providing parameters as part of the method call)
Moves the parameter binding away from the call site (granted, this would probably mean "moves them to the previous LOC", but still)
It's no longer obvious which method uses which property values
Take an instance of this object and just add a few threads for instant fun
Suggestions:
Make both IGetObjects and GetObjectsManager generic so that you don't lose type safety. This loses you the ability to treat different managers polymorphically, but what is the point in that? Each manager will be in the end specialized for a specific type of object, and unless you know what that type is then you cannot really use the return value of the getter methods. So what do you stand to gain by being able to treat managers as "manager of unknown"?
Look into rewriting your GetX methods to accept an Expression<Func<T, bool>> instead of bare values. This way you can use lambda predicates which will make your code massively more flexible without really losing anything. For example:
helper.GetItem(i => i.DataStoreID == 42);
helper.GetList(i => i.DataStoreName.Contains("Foo"));
The first code samples look quite similar to the Repository Pattern. I think this is what are you trying to apply. The last sample is not good and Jon told you why. However, instead of reinventing the wheel, read a bit about the Repository (lots of questions about it on SO) because, if I understood correctly, this is what you really want.
About reuse, not many things and especially persistence interface are reusable. There is the Generic Repository Pattern (I consider it an anti-pattern) which tries to accomplish that but really, do all the application needs the same persistence interface?
As a general guideline, when you design an object, design it to fullfil the specific application needs, if it happens to be reused that's a bonus, but that's not a primary purpose of an object.
It is not a good idea. Based on these examples you would be better off with a generic interface for the varying return type and parameters of GetItem/GetList. Though honestly the prevalence of Managers, the use of something cas vague as GetItem in multiple places and trying to fit your solution into design patterns (rather than defining the solution in terms of the patterns) are huge code smells to me for the wider solution.
Consider this example
The Interface
interface IBusinessRules
{
string Perform();
}
The Inheritors
class Client1BusinessRules: IBusinessRules
{
public string Perform()
{
return "Business rule for Client 1 Performed";
}
}
class Client2BusinessRules: IBusinessRules
{
public string Perform()
{
return "Business rule for Client 2 Performed";
}
}
class Client3BusinessRules: IBusinessRules
{
public string Perform()
{
return "Business rule for Client 3 Performed";
}
}
The factory class
class BusinessRulesFactory
{
public IBusinessRules GetObject(int clientIdentityCode)
{
IBusinessRules objbase = null;
switch (clientIdentityCode)
{
case 1:
objbase = new Client1BusinessRules();
break;
case 2:
objbase = new Client2BusinessRules();
break;
case 3:
objbase = new Client3BusinessRules();
break;
default:
throw new Exception("Unknown Object");
}
return objbase;
}
}
sample usage:
class Program
{
static void Main(string[] args)
{
BusinessRulesFactory objfactory = new BusinessRulesFactory ();
IBusinessRulesFactory objBase = objfactory.GetObject(2);
Console.WriteLine(objBase.Perform());
objBase = objfactory.GetObject(3);
Console.WriteLine(objBase.Perform());
Console.Read();
}
}
My question is, how about I add another method on the ALgorithm1 Class
but not in the interface because im going to just use it on special scenario?
class Client1BusinessRules: IBusinessRules
{
public string Perform()
{
return "Client1 Business rules is Performed";
}
public string Calculate()
{
return "Additional functionality for CLient1";
}
}
how Am I suppose to call that on the UI something like this
objBase = objfactory.GetObject(1);
Console.WriteLine(objBase.Calculate());
Is there any other solution? thanks in advance
EDIT: I rewrite it to resemble my current project design
I presume you are using the factory class in order to:
have a standard facade accepting parameters that lead to business rule selection and provisioning
encapsulate business rule provisioning
decouple the users from actual implementations of IBusinessRules
Hence I would solve your problem by introducing new interface
interface IComputableRules : IBusinessRules
{
string Calculate();
}
As long as you follow the interface-based design, there's nothing wrong about casting the actual instance to an interface different from IBusinessRules.
IBusinessRules businessRule = objFactory.GetObject(...some input...)
...
// check if the computable service is supported and print the result
IComputableRules computable = businessRule as IComputableRules;
if (computable)
{
Console.WriteLine(computable.Calculate());
}
Here you can think of you business rule classes as service providers, that guarantee some basic service, plus optional additional services depending on the nature of the business rule.
Note: By turning the BusinessRulesFactory into a generic class you might make the indication of a specific service a part of the factory contract, and make sure the returned business rule implementation will support a particular (otherwise optional) service.
class BusinessRulesFactory<TService> where TService : IBusinessRules
{
public TService GetObject(int clientIdentityCode)
{
// ... choose business rule in respect to both clientIdentityCode and TService
}
}
In case where you wouldn't require a specific additional service to be available, you'd just use IBusinessRules as the actual type parameter.
The whole point of the factory pattern is to return the proper implementation of a contract so that the consumer shouldn't worry about how to instantiate it but simply invoke its methods. You could always test the actual type, cast to it and invoke the method but that's a very bad design and I wouldn't recommend it. The consumer shouldn't know anything about the actual type. You will need to rethink your design.
If you want to stick to the current architecture you can introduce a new interface declaration
interface ICalculationRules
{
string Calculate();
}
Now let modify Client1BusinessRules by adding the interface declaration:
class Client1BusinessRules: IBusinessRules, ICalculationRules
{
// everything remains the same
}
Modify your calling code like this:
var objBase = objfactory.GetObject(1);
Console.WriteLine(objBase.Calculate());
var calcBase = obj as ICalculationRules;
if (calcBase != null) calculable.Calculate();
Maintenance implication: Every time you introduce a new interface, you have to touch all your calling code. Since you posted that this code is placed in the UI code, this can get quite a mess.
Each interface you are introducing just means added behaviour to a class. If you have a large range of different behaviours, then the solution above my not feel right, because there is always the need to use the as operation and conditional execution a method. If you want to stick to some classic design pattern this variability of behaviour can be countered with the Decorator Pattern or the Strategy Pattern. They can be smoothly combined with the Factory Pattern.
There are many approaches that can be employed in this case, and it depends on the cost you're willing to put in order to get the value.
For example, you can go with simple casting. You'll get the algorithm object from the factory, cast it to the proper (specific) algorithm object, and then call the "Calculate" function.
Another option - a much more generic one, that would also require much more code - would be to supply a querying mechanism within the base class, that will supply information about the available functionality within the object. This is somewhat comparable to querying for interfaces in COM.
The important questions you need to ask yourself is:
1. How many times will you need to implement specific functionality?
2. Is there a way you can solve the problem with added polymorphism stemming from the base class?
3. Will users of the derived objects know that they are using the specific object, or do you want them to be ignorant of the actual type?
In general what I personally do in such cases is start with the simplest solution (in this case, specific casting and calling the function), and go back and refactor as I go, when I have some more data about the domain. If you're sensitive to "smelly code", you'll get to a point where you see there's too much clutter and you'll refactor it into a better solution.
I would modify it like this
interface IBusinessRules
{
string Perform();
bool CanCalculate { get; }
string Calculate();
}
and add an abstract base class (optional but recommended for further extensibility)
public abstract class BusinessRules : IBusinessRules {
protected BusinessRules() {
}
protected virtual bool CanCalculateCore() {
return false; // Cannot calculate by default
}
protected virtual string CalculateCore() {
throw new NotImplementedException("Cannot calculate");
}
protected abstract string PerformCore();
#region IBusinessRules Members
public string Perform()
{
return PerformCore();
}
public bool CanCalculate
{
get { return CanCalculateCore(); }
}
public string Calculate()
{
return CalculateCore();
}
#endregion
}
So the call site now looks neat:
objBase = objfactory.GetObject(1);
if (objBase.CanCalculate) {
Console.WriteLine(objBase.Calculate());
}
One big problem of extending the interface is, it gives the caller no hint at all that you might support that interface as well.
This is a domain modelling issue and relates to what you mean by BusinessRule and IBase in your problem domain.
What is IBase? Sounds like it should be called IBusinessRule. In which case, what does Calculate mean in the context of a "business rule". If it has a generic meaning in your domain then IBusinessRule should implement it, as should the other classes, even if only as an empty method.
If it doesn't have generic meaning in your domain then your class should implement another interface ICalculable (IAlgorithm?) that has Calculate, which you call as:
ICalculable calculable = obj as ICalculable;
if ( calculable != null ) calculable.Calculate();
All of our reports are created from object graphs that are translated from our domain objects. To enable this, we have a Translator class for each report, and have been using Dependency Injection for passing in dependencies.
This worked great, and would yield nice classes structured like this:
public class CheckTranslator : ICheckTranslator
{
public CheckTranslator (IEmployeeService empSvc
, IPaycheckService paySvc)
{
_empSvc = empSvc;
_paySvc = paySvc;
}
public Check CreateCheck()
{
//do the translation...
}
}
However, in some cases the mapping has many different grouping options. As a result, the c-tor would turn into a mix of class dependencies and parameters.
public class CheckTranslator : ICheckTranslator
{
public CheckTranslator (IEmployeeService empSvc
, IPaycheckService paySvc
, bool doTranslateStubData
, bool doAttachLogo)
{
_empSvc = empSvc;
_paySvc = paySvc;
_doTranslateStubData = doTranslateStubData;
_doAttachLogo = doAttachLogo;
}
public Check CreateCheck()
{
//do the translation...
}
}
Now, we can still test it, but it no longer really works with an IoC container, at least in a clean fashion. Plus, we can no longer call the CreateCheck twice if the settings are different for each check.
While I recognize it's a problem, I don't necessarily see the right solution. It seems kind of strange to create a Factory for each class ... or is this the best way?
Shot in the dark here, but could you move those parameters to the method instead?
In other words:
public Check CreateCheck(bool doTranslateStubData, bool doAttachLogo)
{
//do the translation...
}
Do those parameters have to be passed in via the constructor?
(Note - if your response to this is "there are too many methods for that to be practical", then part of the problem may be that the abstraction is too coarse).
Another option (it's really hard to say without understanding the domain model and injection patterns) would be to introduce a parameter object that is itself managed by the injector:
public interface ICheckConfiguration
{
bool AttachLogo { get; }
bool TranslateStubData { get; }
}
Then inject this with the constructor:
public CheckTranslator (IEmployeeService empSvc, IPaycheckService paySvc,
ICheckConfiguration config)
{
// etc.
}
This should be enough. You can then create a concrete CheckConfiguration class that takes those two bool properties in its constructor, and configure your container to create different instances of the parameter object (interface) based on a higher-level DI parameter.
The last thing I think I should mention is that just because you're using DI doesn't mean that everything has to be managed by the container. It's not such a bad thing to create CheckTranslator objects in an ad-hoc fashion if there's only one kind of "translator". As long as the translator still depends on abstractions, which it does here, then maybe you shouldn't be injecting it at all, just let higher-level DI-enabled classes create them ad-hoc.