Linq2Sql, OOP, DependencyInjection problem - c#

I'm still struggling a bit with OOP concepts and dependency injection so bear with me.
I have generated my Linq2Sql model with a User table and now I would like to be able to send a confirmation email to this user so I created a partial class file for my User object and I felt it was natural to add a SendConfirmationEmail() method to the User class. This method will use a MailService to send the actual email and I would like to use dependency injection to pass in the service so I created a constructor overload on the User object like this
public User(IMailService service) : this()
{
_service = service;
}
The SendConfirmationEmail method would look like this
public void SendConfirmationEmail()
{
_service.SendMail(params...);
}
I realize this is a kind of poor mans dependency injection and I hope to switch to a dependency injection framework later as I am getting more grips on this.
The problem for me is that I need to make a reference from my model dll to my service dll which does not seem right and because I am unsure of how nice my linq2sql generated entities plays with Dependency injection frameworks and OOP concepts (I think ninject looks most promising).
I was hoping someone with a bit more experience than me could tell I'm if I am going in the right direction with this. I know I can make it work but I would like to educate my self in doing it in the correct way in the same step.

I personally would change some things in your architecture:
I don't think that SendConfirmationEmail should be a method on your User object. But should be a method on another object with the user as a parameter. (this also better seperates your Dal from the other logic.
Second in this method use something like this:
Services.Get<IMailService>().SendMail(params ...);
You can implement Services as the folowin (just an example):
public class Services
{
protected static Dictionary<Type, object> services = new Dictionary<Type, object>();
private Services()
{
}
static Services()
{
// hard coded implementations...
services.Add(typeof(IMailService), new DefaultMailServiceImplementation());
}
public static T Get<T>() where T : class
{
Type requestedType = typeof(T);
return services[requestedType] as T;
}
}
By using a "Services"-class (or call it what you like) you add an additional layer between the IOC-framework and your code which makes it easy to change IOC-frameworks. Just change the implementation in the Get method to use one. You can also use a hardcoded temporary solution (until you use an IOC-framework) in the static constructor (like I did in the above example).

The problem with that approach is that much of the time the entity is going to come from the LINQ-to-SQL back-end, and so isn't going to use your constructor (LINQ-to-SQL creates objects in its own way; you cannot force LINQ-to-SQL to use your constructor) - so this would only be useful for the (few) objects you create yourself. Data-binding (etc) will also commonly use the parameterless constructor by default.
I wonder if this wouldn't work better as a utility method that accepts the service, or obtains the service itself via a factory / singleton.

I think you're ok doing this, but you might want to do two additional things to protect yourself from future cross-layer dependency problems:
Create an interface for your User
object. You should do this because
not doing so will mean that
everything that consumes this
business object will have to
reference the LINQ dlls
unnecessarily.
Move your dependency injection from
the constructor into a property.
You do this because constructor
injection tends to limit your
ability to dynamically create your
object. Doing this, though poses a
problem, since you would have to
implement a lot of null checking
code for _service. You can fix this
by creating an "empty"
implementation of IMailService and
make it the default value for
_service.

Related

When using dependency injection in C#, why does calling an interface method automatically call the implemented class' method?

To clarify my question, suppose I have the following very basic statistics interface and class:
public interface IStatistics
{
void IncrementPacketsDiscovered();
}
public class Statistics : IStatistics
{
private int numberOfPacketsDiscovered = 0;
public void IncrementPacketsDiscovered()
{
numberOfPacketsDiscovered++;
}
}
Then suppose I have the following class that receives the injected IStatistics object:
public class Reporter
{
private IStatistics _statistics;
public Reporter(IStatistics statistics)
{
_statistics = statistics;
_statistics.IncrementPacketsDiscovered();
}
}
Why is it that I am able to call the IStatistics method IncrementPacketsDiscovered() on the IStatistics object and it automatically knows to fetch the method definition that was implemented in the Statistics class?
Any help would be greatly appreciated. Thank you!
TLDR; because the injected object that implements IStatistics is an instance of the Statistics class, and it is this way because somewhere else you told the dependency resolver to use Statistics whenever you mention IStatistics..
Note that Statistics.IncrementPacketsDiscovered being called is nothing to do with DI per se, you could write this:
IStatistics x = new Statistics();
x.IncrementPacketsDiscovered();
On the outside, x looks like an IStatistics. On the inside, it is a Statistics. If Statistics did something else (other than just implement the interface) it would be easier to see. It would also probably be more clear what's going on if you had something else that implemented IStatistics, like some sort of FakeStatistics that you use in a test scenario - testing is one such valid reason where you'd switch your program back and forth between different suites of objects.
You could just conceive that somewhere outside of all your code is the dependency resolver, a thing created by Microsoft*. It did that first line of code above for you, and later when you said you wanted to have a Reporter it looked and saw "the constructor takes a parameter of anything that implements IStatistics, and I just happen to have an instance of Statistics here that fits that requirement, so I'll pass that into the Reporter constructor.." because that is what it is configured to do/that is its job.
If you had a FakeStatistics that you used for testing, and a context where you reconfigured the injector to create and supply fake objects then it suddenly starts to make sense why it's a useful way to engineer - you don't have to have 100 places where you said new Statistics where you go through and change them all to say new FakeStatistics. It's also useful to be writing a class and suddenly realize "this class needs statistics.." you add a single argument IStatistics x to the constructor, hit Ctrl . and pick the option to add a property for it and that class now has access to a suitable implementation of IStatistics, supplied by the resolver. You don't have to chase up through everywhere you said new MyXClass(param1, param2) and change it to say new MyXClass(param1, param2, someStatistics) because the job of newing all your objects is the responsibility of the resolver
By using interfaces and coding up such that "any object that implements this interface can sensibly be used as an input argument to this class" you then open it up to the possibility that a "class instance lookup and provider service" can wire all your app together just by "rummaging around in its currently configured bag of objects for one that will do the job" (and then you change what's in the bag depending on the context)
So where did you put things in the bag? In the part of the program where you configured the resolver, methods like AddScoped, AddTransient, AddSingleton have the dual purpose of mapping a type of class to a type of interface and also configure what sort of lifetime the instance has- resolvers manage instances for you and create/destroy them over the lifetime you specify by which Add* method you use
* With this statement I am, of course, making a gross assumption as to which injector you're using. There are other DI/IoC frameworks available for C#, created by others. The overarching concept remains the same; the more you can get the computer to write your code for you, the quicker, easier and more reliable it can be. Establishing dependenceies between objects in your program is one such place where it can make sense to hand it off to software rather than writing it yourself

Method injection (DI, .NET, IOC)

I am using .NET (MVC5, Web API etc). I understand constructor injection just about (fairly new to using it in anger).
I have a class with a method that has a dependency. I don't want to use constructor injection because then I will be creating the dependent object every time this class is instantiated (and most of the methods don't use this dependent object).
So I thought method injection sounded like it might be the thing. However I can't figure out how to do it (I am using Autofac).
So if my method is
void DoSomething(string x, int y)
and that method needs to use an implementation of IMyService, how do I do this without using the constructor injection?
The only method injection technique I have seen is one where effectively a method is called at instantiation. This doesn't seem to help my case, it still means that all instances create this dependency even if I am going to call a method that doesn't need it.
I'm sure it is something simple but I can't figure it out right now. Could you help me with an example please?
UPDATE
this is the crux of it. I like the idea of Lazy suggested by Jim and will try this. So is method injection as I suspected and if so I don't really understand the point of it - why use it instead of constructor injection?
public class MailService {
// lots of methods that don't need PlayerDataService
public void SendPlayersEmail() {
var service = new PlayerDataService();
var players = service.GetPlayers();
foreach(var player in players) {
SendEmail(player);
}
}
}
I don't want to use constructor injection because then I will be creating the dependent object every time this class is instantiated (and most of the methods don't use this dependent object).
There's the problem. Break that functionality out into a new class.
That is, at least in my experience, the best solution when a method does not fit into the rest of the class (or have dependencies that are not used anywhere else).
You should also consider that object allocation is pretty cheap, you need millions of allocations per second before the performance is hurt (unless you are using Ninject ;))
If the cost of instantiating your object during construction is an issue, you can wrap it in a Lazy<> to avoid unnecessary construction. This will cause your dependency to be constructed on the first call to the lazy's .Value.

Am I trying to use Ninject incorrectly, or am I missing something obvious?

I'm developing an ASP.NET MVC web application. I wanted to build a nice data layer that abstracted everything. So like a good data layer, the controller wouldn't talk directly to the database.
Now, of course, inside the data layer there's a lot of things that WILL need to talk to the database. I'd like all these objects to use the same data context (this is using Linq2SQL, but not thinking that should matter much.) So yes, this is sounding a lot like a repository or unit of work pattern. It kind of is, except I'm mostly just implementing the unit of work part.
Now, my problem is how do i get the data context to all the classes that need it? I had thought Ninject could just inject it where I need. And it does, IF the object I'm constructing only has one parameter in it's constructor.
So this seems to work well:
public class InjectedFoo
{
InjectedFoo(IInjectable ii) {/*stuff*/}
}
This, however, gives me compiler errors:
public class InjectedFoo
{
InjectedFoo(Object stuff, IInjectable ii) {/*stuff*/}
}
Which, yes, makes perfect sense. After all the compiler doesn't know that Ninject will be creating that second parameter. But at the same time, with only one parameter Ninject figures it out... which kind of seems like the point. So how can I do it with those two parameters?
Now, let's up the ante a bit:
public static class FooFactory
{
public static MakeFoo(int fooID, IInjectable ii)
{
}
}
So now I want a class to use the existing data context without ever actually being instantiated. And I need to pass it the ID of the object I want. So of course I have the same problem with the second parameter not being passed in so the compiler complains, but I can't even use property injection because I can't have a non-static property. (I know I could use a static property, but I don't know that it would be safe.)
So I feel like I'm either using Ninject incorrectly, or just plain missing something that handles this. Unfortunately all the documentation and examples seem to focus on very simple 1-argument constructors...

DAL Design/Load methods with NHibernate

public MyClass(int someUniqueID)
{
using(//Session logic)
{
var databaseVersionOfMyClass = session.CreateCriteria(/*criteria*/)
.UniqueResult<MyClass>();
//Load logic
}
}
The code sample above is my current direction, although I've reached a point where I need a bit of a sanity check.
With NHibernate(I'm green in this area), is it common or best practice to instantiate an object from a database within the class constructor? The alternative I believe, would be to have a static method that returns the object from the database.
I've also come across a relevent question regarding constructors vs factory methods, however I don't believe this implementation fits the factory methodology.
To add an additional question onto the above, if instantiation within the constructor is the way to go, I've always used some sort of Load() method in the past. Either a specific private method that literally matches properties from the returned db object to the new class, or via a generic reflective method that assumes property names will match up. I'm curious if there is another way to "load" an object that I've missed.
I do not like this approach.
IMHO , it is better to implement some kind of repository which retrieves instances of persisted classes for you.
As an alternative, you could also follow the ActiveRecord approach, where you could have a static 'Load' method inside your class, and an instance method 'Save' for instance. (Take a look at Castle ActiveRecord).
But, for me, I prefer the Repository approach.

Is this a good factory method implementation?

I'm working on a module that requires a strictly decoupled interface. Specifically, after instantiating the root object (a datasource), the user's only supposed to interact with the object model via interfaces. I have actual factory objects (I'm calling them providers) to supply instances that implement these interfaces, but that left the clumsiness of getting the providers. To do so, I've supplied a couple methods on the datasource:
public class MyDataSource
{
private Dictionary<Type, Type> providerInterfaceMapping = new Dictionary<Type, Type>()
{
{ typeof(IFooProvider), typeof(FooProvider) },
{ typeof(IBarProvider), typeof(BarProvider) },
// And so forth
};
public TProviderInterface GetProvider<TProviderInterface>()
{
try
{
Type impl = providerInterfaceMapping[typeof(TProviderInterface)];
var inst = Activator.CreateInstance(impl);
return (TProviderInterface)inst;
}
catch(KeyNotFoundException ex)
{
throw new NotSupportedException("The requested interface could not be provided.", ex);
}
}
}
I've modified some details on the fly to simplify (e.g., this code snippet doesn't include the parameters passed to the implementation instance that's created). Is this a good general approach for implementation of a factory method in C#?
You should rather take a step back and ask whether using a factory method at all is a good idea? In my opinion, it is not.
There are more than one issue with factory methods, and your example illustrates several:
You need to have a hard reference to the implementation (FooProvider in addition to IFooProvider), which is exactly the situation you are trying to avoid in the first place. Even if the rest of your code only consumes IFooProvider, your library is still tightly coupled to FooProvider. Some other developer may come by and start using FooProvider directly if he/she isn't aware of your factory method.
You only support implementations that have default constructors, since you are using Activator.CreateInstance. This prevents you from using nested dependencies.
Instead of trying to manually control dependencies, I would recommend that you take a look at Dependency Injection (DI). Whenever your code needs an IFooProvider, supply it with Constructor Injection.
Don't reinvent your own implementation of dependency injection, use an existing library like Spring.NET or the Microsoft Unity application block.
Injecting dependencies is a common programming problem that you shouldn't have to solve yourself. There are some nice lightweight libraries out there (I mentioned a couple above) that do the job well. They support both declarative and imperative models of defining dependencies and are quite good at what they do.
Technically this is fine, however most times when I see a factory it usually returns the same type interface, for instance something like IProvider rather than IFooProvider or IBarProvider which to me doesn't make sense. If you are going to have FooProvider and BarProvider then why have different interfaces for them. I would use one interface IProvider and have FooProvider and BarProvider implement that.
Regardless of the rightness or wrongness of using the factory method (as that is not what you asked about!), your implementation looks fine to me.
Something that may work for you better than hardcoding the type mapping is putting that info in a configuration file and loading it in your app.
For what it is worth I use this pattern all the time and have abstracted some of this sort of logic into a reusable assembly. It uses reflection, generics and attributes to locate and bind the concrete types at runtime. http://www.codeproject.com/KB/architecture/RuntimeTypeLoader.aspx
This helps to address Mark's concern because implementation types are not hardcoded, and further the implementation types are determined by the installation, not in project assembly references.

Categories