c# constructor injection and constructor overloads - c#

I'm using constructor injection for the first time and wish to write my code defensively.
Therefore if I have a class with a constructor and a save method as below:
public SomeConstructor(string name, Object someObject)
{
_name= name;
_someObject= someObject;
}
public void Save()
{
// Does a database save
}
But then need to create another related method in this Class that doesn't need the _someObject so I create an overloaded chained constructor as:
public SomeConstructor(string name) : this(name, null)
{
}
How can I successfully stop someone instantiating the class with this second constructor with 1 parameter and using the Save() which has someObject as null?
I'm not using an injection tool.
Above is a simple example and in it, you are correct I could just throw an exception for a null just as I would if a property was not set.
What I wanted to avoid was a series of validation checks at the start of each method.

Use the friction you are experiencing as a warning system. It's really telling you that you're likely moving towards low cohesion and violation of the Single Responsibility Principle.
If this is the case, refactor the class into two separate classes.

You may prevent that situation with a run-time exception like InvalidOperationException.
If some instantiated the class with the two-parameters-constructor and tries to call Save, just check if "someObject" is null, and if it's so:
throw new InvalidOperationException("This method cannot be invoked in current object state");
In the other hand, if this second constructor would be used by your library and third-party library developers wouldn't be allowed to use it, this constructor should have the internal modifier.

The IoC it is just a way to dinamically resolve the dependency but doens't solve any OO problem.
I would focus on a good OO design instead of try to find a way to cheat the framework forcing to use a contractor instead of another.The question is how would you do that if you were not using an IoC framework?
probabily checking if SomeObject is null?

public void Save()
{
if (_someObject == null)
throw new InvalidOperationException();
}
I guess that this is obvious. But you really can't create a contract in which the type is constructed differently unless you also change your SomeConstructor type to work like a decorator pattern. What the decorator pattern does is that it let's you build the inheritance hierarchy at run-time not compile-time.
You can then create different objects depending on what operations are allowed internally. This is some work for something which can easily be handled with a pre-condition for the Save method. But maybe this is what you need. And if you did it you could stipulate your contract in the constructor of SomeConstructor.
Here's an example:
interface ISomeConstructor
{
void Save();
}
class SomeConstructor
{
ISomeConstructor impl;
public SomeConstructor(string name, object someObject)
{
impl = new StringAndObject(name, someObject);
}
public SomeConstructor(string name)
{
impl = new JustString(name);
}
public void Save()
{
impl.Save();
}
}
The types StringAndObject and JustString implements ISomeConstructor and they can handle the Save method as they see fit.
This is a slight variation of the decorator pattern as normally you'd expect ISomeConstructor to be passed as an argument to the constructor as well.

Related

Virtual Member in Constructor, workaround

I have a class, BaseEmailTemplate, that formats an email, and I want to create a derived type that can overrule the defaults. Originally my base constructor -
public BaseEmailTemplate(Topic topic)
{
CreateAddresses(topic);
CreateSubject(topic);
CreateBody(topic);
}
... (Body/Addresses)
protected virtual void CreateSubject(Topic topic)
{
Subject = string.Format("Base boring format: {0}", topic.Name);
}
And in my derived
public NewEmailTemplate(Topic topic) : Base (topic)
{
//Do other things
}
protected override void CreateSubject(Topic topic)
{
Subject = string.Format("New Topic: {0} - {1})", topic.Id, topic.Name);
}
Of course this leads to the error discussed here: Virtual member call in a constructor
So to be absolutely blunt about this - I don't want to have to call the same methods in every derived type. On the flip side, I need to be able to change any/all. I know another base has a different subset of addresses, but the body and subject will be the default.
All three methods must be called, and the ability to alter any one of them needs to be available on a per derived basis.
I mean the thing everyone seems to be saying is an unintended consequence of using virtual seems to be my exact intention.. Or maybe I'm in too deep and singly focused?
UPDATE- Clarification
I understand why virtual members in the constructor is bad, I appreciate the answers on that topic, though my question isn't "Why is this bad?" its "Ok this is bad, but I can't see what better serves my need, so what do I do?"
This is how it is currently implemented
private void SendNewTopic(TopicDTO topicDto)
{
Topic topic = Mapper.Map<TopicDTO , Topic>(topicDto);
var newEmail = new NewEmailTemplate(topic);
SendEmail(newEmail); //Preexisting Template Reader infrastructure
//Logging.....
}
I'm dealing with a child and grandchild. Where I came in there was only newemailtemplate, but I have 4 other tempaltes I now have to build, but 90% of the code is reusable. Thats why I opted to create BaseEmailTemplate(Topic topic). BaseTemplate creates things like Subject and List and other things that SendEmail is expecting to read.
NewEmailTemplate(Topic topic): BaseEmailTemplate(Topic topic): BaseTemplate, IEmailTempate
I would prefer not have to require anyone who follows my work have to know that
var newEmail = new NewEmailTemplate();
newEmail.Init(topic);
is required every single time it is used. The object would be unusable without it. I thought there were many warnings about that?
[10.11] of the C# Specification tells us that object constructors run in order from the base class first, to the most inherited class last. Whereas [10.6.3] of the specification tells us that it is the most derived implementation of a virtual member which is executed at run-time.
What this means is that you may receive a Null Reference Exception when attempting to run a derived method from the base object constructor if it accesses items that are initialized by the derived class, as the derived object has not had it's constructor run yet.
Effectively, the Base method's constructor runs [10.11] and tries to reference the derived method CreateSubject() before the constructor is finished and the derived constructor can be run, making the method questionable.
As has been mentioned, in this case, the derived method seems to only rely upon items passed as parameters, and may well run without issue.
Note that this is a warning, and is not an error per se, but an indication that an error could occur at runtime.
This would not be a problem if the methods were called from any other context except for the base class constructor.
A factory method and an initialize function is an effective workaround for this situation.
In the base class:
private EmailTemplate()
{
// private constructor to force the factory method to create the object
}
public static EmailTemplate CreateBaseTemplate(Topic topic)
{
return (new BaseEmailTemplate()).Initialize(topic);
}
protected EmailTemplate Initialize(Topic topic)
{
// ...call virtual functions here
return this;
}
And in the derived class:
public static EmailTemplate CreateDerivedTemplate(Topic topic)
{
// You do have to copy/paste this initialize logic here, I'm afraid.
return (new DerivedEmailTemplate()).Initialize(topic);
}
protected override CreateSubject...
The only exposed method to create an object will be through the factory method, so you don't have to worry about the end user forgetting to call an initialize. It's not quite as straight-forward to extend, when you want to create further derived classes, but the objects themselves should be quite usable.
A workaround could be to use your constructor to initialize a private readonly Topic _topic field, and then to move the three method calls to a protected void Initialize() method which your derived types can safely call in their constructor, since when that call occurs the base constructor has already executed.
The fishy part is that a derived type needs to remember to make that Initialize() call.
#Tanzelax: That looks ok, except that Initialize always returns EmailTemplate. So the static factory method won't be quite as sleak:
public static DerivedEmailTemplate CreateDerivedTemplate(Topic topic)
{
// You do have to copy/paste this initialize logic here, I'm afraid.
var result = new DerivedEmailTemplate();
result.Initialize(topic);
return result;
}
This answer is mostly for completeness, in case somebody stumbles upon this question these days (like me).
To avoid a separate Init method while still keeping things simple, one thing that could feel more natural (IMO) to users of the code would be to have Topic as a property of the base class:
// This:
var newEmail = new NewEmailTemplate { Topic = topic };
// Instead of this:
var newEmail = new NewEmailTemplate();
newEmail.Init(topic);
Then, the property setter could take care of calling the abstract methods, such as:
public abstract class BaseEmailTemplate
{
// No need for even a constructor
private Topic topic;
public Topic
{
get => topic;
set
{
if (topic == value)
{
return;
}
topic = value;
// Derived methods could also access the topic
// as this.Topic instead of as an argument
CreateAddresses(topic);
CreateSubject(topic);
CreateBody(topic);
}
}
protected abstract void CreateAddresses(Topic topic);
protected abstract void CreateSubject(Topic topic);
protected abstract void CreateBody(Topic topic);
}
Pros:
An email template can be defined in a single line with an intuitive syntax
No factory methods or third classes involved
Derived classes only need to worry about overriding the abstract methods, and not about calling the base constructor (but you may still want to pass other variables as constructor arguments)
Cons:
You still need to consider the possibility of users forgetting to define Topic, and handle the case of it being null. But I would argue you should do that anyway; somebody could explicitly pass a null topic to the original constructor
You are publicly exposing a Topic property without really needing to. Perhaps you intended to do this anyway but, if not, it might not be very ideal. You could remove the getter, but that might look a bit odd
If you have more than one inter-dependent property, the boilerplate code would increase. You could try to group all these into a single class, so that only one setter still triggers the abstract methods

Is using var + basic dependency factory more loosely coupled than C# interfaces?

This is a general design question. We often use interfaces to decouple components, write to an interface not an implementation etc. Sometimes interfaces are used w/ a basic injection technique, such as,
interface IMyInterface
{
void DoSomething();
}
static class IMyInterfaceFactory
{
public static IMyInterface GetInstance()
{
return new MyInterfaceInstance();
}
}
class IMyInterfaceConsumer
{
IMyInterface mInterface;
public IMyInterfaceConsumer()
{
this.mInterface = IMyInterfaceFactory.GetInstance();
}
public void UseTheInterface()
{
this.mInterface.DoSomething();
}
}
My question is about using the var keyword instead. Not even using a true C# interface, but still creating an 'interface', in the design sense,
static class IMyInterfaceFactory
{
// of course, this doesnt need to be a single instance
static MyInterfaceInstance mSingleInstance;
// no longer programming to the interface, just returning the instance
public static MyInterfaceInstance GetInstance()
{
// null coalesce
return mSingleInstance ?? (mSingleInstance = new MyInterfaceInstance());
}
}
class IMyInterfaceConsumer
{
public void UseTheInterface()
{
// shorthand way, could also omit var, too
var myInterface = IMyInterfaceFactory.GetInstance();
myInterface.DoSomething();
}
}
This way I still only need to change the factory once, and as long as whatever instance it returns supports the methods that need to be consumed, it will work. The advantage however is that the producing and consuming objects dont need to even know about any explicit interface, none exists. It could also cleanly support an interface with more than just a couple methods (prevent bloated interface declarations).
One obvious downside is that everytime you want to consume a method from the 'interface', the factory will potentially have to re-instantiate the class, unless there is a single instance cached (as above) or some memoization technique used.
Pros/cons of this approach? Is this a common practice?
There is nothing dynamic or loose about the var keyword. It triggers static type inference at compile time.
Your second piece of code behaves identically to
public void UseTheInterface()
{
// shorthand way, could also omit var, too
MyInterfaceInstance myInterface = IMyInterfaceFactory.GetInstance();
myInterface.DoSomething();
}
The factory function is still strongly typed. In fact, by removing the interface, you've made consumer code much more tightly coupled.
Var keyword is still technically strongly typed, so your code does know what class/interface it is. If you planned on dumping it into an object then we are saying that the rest of your code has no clue what is coming out of that factory. I wouldn't suggest that though since that causes you to cast that object to utilize anything in it.
I'm not sure where you are trying to go with the "prevent bloated interface declarations" but you could do polymorphism through extending a base class or an abstract class as well. That would make it so any code that is common between the child classes could be left alone and any specific code (methods or properties) for each child class could be overridden.
If you are looking to change out the interface all together you will need to implement an interface in the interface, see this post. So you will basically have interface A only have the method DoStuff() and other interfaces that inherit from this interface could be used polymorphically like you are describing.
interface A
{
DoStuff();
}
interface B : A
{
DoSomethingElse();
}
class C : B
{
DoStuff(){}
DoSomethingElse(){}
}
By the way, your "single instance cached" code above is close to something called a singleton pattern.

Should I accept the same object as a parameter and return it or just accept it as a parameter?

I have the following interface:
public IStateMachineConfigurator
{
??? Configure(StateMachine machine);
}
In the implementation I am calling some of the StateMachine methods to configure it like this:
machine.Configure(States.State1)
.Allow(Triggers.Trigger1);
The question is, can I rely on the fact that the StateMachine object is a reference or should I use a return value or a return parameter like ref/out?
EDIT:
The state machine itself comes from a library and thus I cannot decide it's implementation.
If you wanna go with the builder pattern then your effectivly return the mutable state that is being passed in. This is perfectly fine, if you wanna go down that road. This is how the StringBuilder class operates and on a somewhat different note jQuery. It can be very nice for building objects in a compact and readable fashion. However, those objects should be designated as such. Builder objects and preferably not take on more than necessary.
Yes, you can rely on the fact that StateMachine is an object reference. Some people might choose to return a bool or perhaps an enum to give the programmer some kind of hint as to what happened in the Configure method (ie. success/fail/no change/etc.). Others might choose to throw an exception in the event something goes wrong.
All are perfectly valid, just be careful how deep you chain the method together, as something like:
machine.Configure().Allow().someMethod().someOtherMethod()
Gets difficult to debug and trace.
Instead of creating a Configurator, I would rather craete a Configuration object and pass it in the StateMachine constructor. This makes it cleare to the users of StateMachine class that they have to provide it with a valid configuration before using it.
class StateMachineConfiguration
{
public IEnumerable<State> States { get; private set; }
public IEnumerable<Trigger> Triggers { get; private set; }
}
class StateMachine
{
public StateMachine(StateMachineConfiguration config)
{
if(config == null)
throw new ArgumentNullException();
this.Configure(config.States);
this.Allow(config.Triggers);
}
}

How to implement saving/loading interface with parameterized constructor?

I know interfaces cannot define constructors. Here's what I wish I could do:
public interface SavableObject {
void Save(ObjectSaver saver);
SavableObject(ObjectLoader loader); //This, obviously, doesn't work
}
//Loading an object inside ObjectLoader:
T LoadObject<T>() where T : SavableObject {
return (T)Activator.CreateInstance(typeof(T), this);
}
And I could do this if I took out the line that didn't work, and there would just be a runtime error when trying to load (or possibly save, if I put an assert in there) the object if it didn't have the constructor. I'm just wondering if there's any way to require a class to have a particular constructor that can be used with the Activator. Can I use a custom attribute somehow, and require that attribute to be on the class? Or must I rely on runtime checks to load and save data?
I know I could have a parameterless constructor and a Load(ObjectLoader) method but I don't necessarily want to have a parameterless constructor available to abuse for other purposes.
what about ISerializable?
In brief I suggest you use generics as most factories do.
public interface SavableObject<T> : where T : new
{
void Save(IObjectSaver<T> saver);
SavableObject<T> Load(ObjectLoader loader); //This, obviously, doesn't work
}
However, you seem to have turned it on it head. The class is doing what factory must do. So I do not think it is such a good idea to pass the factory to the entity itself and that is part of the problem you are experiencing in the design.
If you are not afraid of using Reflection, like Activator that you have shown, you can do little trick I tend to use:
Make parameterless constructor that is protected
Make Load method, that is also protected (or private, I tend to use virtual protected so I support inheritance)
Create new object using this non-public constructor (through reflection - you can't create instance of your class "just like that" using new operator)
Invoke load method (also using reflection - no one will call it later).
I don't know if this will work for you, but I used that method when I needed to deserialize pretty big game state and it was pretty fast, eventhough all this reflection (for many reasons I did not wanted to use built-in serialization methods and Factory Pattern wouldn't do, so I tend to treat this method as something that may be useful if other methods fail, on the other hand, if I could - I would probably use built-in serialization for simplicity).
How about adding a property on your interface:
public interface SavableObject
{
void Save(ObjectSaver saver);
ObjectLoader ObjectLoader {get; set;}
}
Then in your factory:
T LoadObject<T>() where T : SavableObject
{
var result = (T)Activator.CreateInstance(typeof(T));
result.ObjectLoader = this;
return result;
}
Based on your question and comments.
I think you should do it at runtime using reflection.
Combining constructors and interfaces is ilogical from its core. Interface is about what concrete instance can do, not how to initialize it. This can only be achived using abstract class.
Maybe using factory to create instance of the class?
Also I don't think you can get better speed than default ISerializable implementation. Unless you are .NET GURU and have years of time for it.
Short answer: It's not possible, I guess. There are no attributes or generalizations I can use to require a specific kind of constructor on a class.

How do you make a Generic Generic Factory?

I am working on a client (Silverlight) interface to a collection of webmethod. And I am trying to avoid writing any custom code for every webmethod. So I have created a ServiceCall<TResult> to handle each call, TResult specifies the return type of the service (I use XmlSerializer to create the returned instance). The client class exposes a function matching each webmethod, and all that function has to do is to create a new instance of ServiceCall<TResult>, with the TResult specified as the expected return type of the method.
And that works just fine.
I am also using Ninject (dependency injector) to try and keep everything independent. Ninject supports open generics, whichs works out great with my ServiceCall<TResult>.
But it also means that I'm injecting a reference to the Ninject container. Which hides the dependency on ServiceCall<TResult> being bound to the container. So I would like to instead inject a factory for creating my ServiceCall<TResult> instances. Which is not tricky, but I would like to make it a generic generic factory. Meaning I would like to have something like Factory<T<>> which would have a method public T<TU> Createinstance<TU>().
But I have no idea how I could create generic class with a type parameter that is itself an open genric.
Is it event posible in .Net? - Or do I have to create a specific ServiceCallFactory?
Edit:
I am using interfaces for the dependencies, but there's no need to mix them into the question here, so I edited that out of the question.
In responce to Timwi:
The common way to use dependency injection (DI) is to bind an interface to your implementation, only the container knows of these bindings. You then code up against the interfaces instead. This brings a ton of advantages. More than I can mention here.
Anyway it also rules out the static classes (since that would be a dependency on a specific class). Instead I'll instruct the container (Ninject in this case) to always hand me the same instance for the factory interface, in a singleton like behavior.
This rules out the public static class Factory<T> option, because it is static, and if it is not static I would need to now every type of T I'm gonna use, somewhat defeating the purpose of having a generic class.
The suggestion of having a non-generic class with a "totally generic" method (as in I pass in ServiceCall<MyResult> instead of just MyResult), is what more or less what I am doing now (minus the static class part). The Ninject container has an Get method that work like your second suggestion.
The problem with this is two part; firstly it makes my code directly dependent on one container (Ninject), but this is not really that big a problem to me. What does annoy me is that if you look at me Client from the outside, you'll only see a dependency on Ninject. You wont know until you run try to make a call that client needs an implementation of ServiceCall registered with Ninject to work.
But if the Client contructor took a parameter of type Factory>, then it would much clearer.
In any case I would think this would be a common issue, so either there a common solution, or it is not a common issue and I am trying to do something stupid ;)
I am still not that into dependency injection, so that may very well be the case.
Is this what you are looking for: Generic Factory Pattern
namespace GenericFactoryPatternTestApp
{
public class Factory< T >
{
private readonly Dictionary< string, Type > _factoryDictionary = new Dictionary< string, Type >();
public Factory()
{
Type[] types = Assembly.GetAssembly(typeof (T)).GetTypes();
foreach (Type type in types)
{
if (!typeof (T).IsAssignableFrom(type) || type == typeof (T))
{
// Incorrect type
continue;
}
// Add the type
_factoryDictionary.Add(type.Name, type);
}
}
public T Create< V >(params object[] args)
{
return (T) Activator.CreateInstance(_factoryDictionary[typeof (V).Name], args);
}
}
}
So if I understand you right, you’d have a class looking a bit like this:
public static class Factory<T<>>
{
public static T<TU> CreateInstance<TU>() { /* ... */ }
}
and then you’d call it how? Like this?
var myServiceCall = Factory<ServiceCall<>>.CreateInstance<MyResult>();
What stops you from simply declaring the factory like this...
public static class Factory<T>
{
public static T CreateInstance() { /* ... */ }
}
... or this ...
public static class Factory
{
public static T CreateInstance<T>() { /* ... */ }
}
... and then generating your instance like this?
var myServiceCall = Factory<ServiceCall<MyResult>>.CreateInstance();
var myServiceCall = Factory.CreateInstance<ServiceCall<MyResult>>();
I’m sorry if I’m being dumb, but I’d probably need to know how Ninject works and how it allows you to pass in a factory.

Categories

Resources