What is Ninject and when do you use it? - c#

I have been helping a few friends on a project and there is a class that uses Ninject. I am fairly new to C# and I have no idea what that class is doing, which is why I need to understand Ninject. Can anyone explain what Ninject is and when does one use it(with example if possible)? Or if you can point to some links that would be great too.
I tried this question: Ninject tutorials/documentations? but it didn't really help a beginner like me.

Ninject is dependency injector for .NET, practical realisation of pattern Dependency Injection (form of Inversion of Control pattern).
Suppose you have two classes DbRepository and Controller:
class Controller {
private DbRepository _repository;
// ... some methods that uses _repository
}
class DbRepository {
// ... some bussiness logic here ...
}
So, now you have two problems:
You must initialize _repository to use it. You have several options for doing this:
Manually, within the constructor. But what if the constructor of DbRepository changes? You would need to rewrite your Controller class because code it's dependent upon was changed. It's not hard if you have only one Controller, but if you have a couple of classes that have a dependency on your Repository you have a real problem.
You can use a service locator or factory. But now you have a dependency on your service locator. You have a global service locator and all code must use it. How you will you change the behavior of your service locator when you need to use it in one part of your code for activation logic but for something else in another part of your code? There is only one way - passing the service locator through constructors. But with more and more classes you will need to pass it more and more times. Anyway, it's a good thought but in the long run, it's a bad idea.
class Controller {
private DbRepository _repository;
public Controller() {
_repository = GlobalServiceLocator.Get<DbRepository>()
}
// ... some methods that uses _repository
}
You can use dependency injection. Look at the code:
class Controller {
private IRepository _repository;
public Controller(IRepository repository) {
_repository = repository;
}
}
Now when you need your controller you write: ninjectDevKernel.Get<Controller>(); or ninjectTestKernel.Get<Controller>();. You can switch beetween dependency resolvers as fast as you want. See? It's simple, you don't need to write a lot.
You can't create unit tests for it. Your Controller has a dependency on DbRepository and if you want to test some method that uses repository, your code will go to the database and ask it for data. That's slow, very slow. If your code in DbRepository changes, your unit test on Controller will fall. Only integration test must warn you of 'problems' in this case. What you need in unit tests - is to isolate your classes and test only one class in one test (in ideal - only one method). If your DbRepository code fails, you will think that Controller code failed - and that's bad (even if you have tests for DbRepository and Controller - they both will fail and you can start from the wrong place). It takes a lot of time to determine where the error really is. You need to know that class A is ok, and it was class B where something failed.
When you want to replace DbRepository with something else in all your classes, you have to do a lot of work.
You can't easily control the lifetime of DbRepository. An object of this class is created on initialization of Controller and deleted when Controller is deleted. There is no sharing between different instances of the Controller class and there is no sharing between other classes. With Ninject you can simply write:
kernel.Bind<IRepository>().To<DbRepository>().InSingletonScope();
A special feature of dependency injection - agile development! You describe that your controller uses a repository with interface IRepository. You don't need to write DbRepository, you can simply create a MemoryRepository class and develop Controller while another person develops DbRepository. When work on DbRepository is finished, you just rebind in your dependency resolver that default IRepository is now DbRepository. Have a lot of controllers? All of them will now use DbRepository. That's cool.
Read more:
Inversion of control (wiki)
Dependency injection (wiki)
Inversion of Control Containers and the Dependency Injection pattern (Martin Fowler)

Ninject is an Inversion of Control container.
What does it do?
Suppose you have a Car class that depends on a Driver class.
public class Car
{
public Car(IDriver driver)
{
///
}
}
In order to use the Car class you build it like so:
IDriver driver = new Driver();
var car = new Car(driver);
A IoC containter centralizes the knowledge about how to build classes. It is a central repository that knows a few things. For example, it knows that the concrete class that you need to use to build a car is a Driver and not any other IDriver.
For example, if you are developing a MVC application, you can tell Ninject how to build your controllers. You do so by registering which concrete classes satisfy specific interfaces. At run time Ninject will figure out which classes are needed to build the required controller, and all behind the scenes.
// Syntax for binding
Bind<IDriver>().To<Driver>();
This is beneficial because it lets you build systems that are more easily unit testable. Suppose that Driver encapsulates all database access for Car. In a unit test for Car you can do this:
IDriver driver = new TestDriver(); // a fake driver that does not go to the db
var car = new Car(driver);
There are entire frameworks that take care of automatically creating testing classes for you and they are called mocking frameworks.
For more information:
GitHub/Ninject Home
Inversion of Control
Inversion of Control Containers and the Dependency Injection pattern
Mock Object

Other answers are great but I would also like to point out this Implementing Dependency Injection using Ninject article.
This is one of the best articles I ever read which explains Dependency Injection and Ninject with a very elegant example.
Here's the snippet from the article:
Below Interface will be implemented by our (SMSService) and (MockSMSService), basically the new Interface (ISMSService) will expose the same behaviors of both services as the code below:
public interface ISMSService
{
void SendSMS(string phoneNumber, string body);
}
(SMSService) implementation to implement the (ISMSService) interface:
public class SMSService : ISMSService
{
public void SendSMS(string mobileNumber, string body)
{
SendSMSUsingGateway(mobileNumber, body);
}
private void SendSMSUsingGateway(string mobileNumber, string body)
{
/*implementation for sending SMS using gateway*/
Console.WriteLine("Sending SMS using gateway to mobile:
{0}. SMS body: {1}", mobileNumber, body);
}
}
(MockSMSService) with totally different implementation using the same interface:
public class MockSMSService :ISMSService
{
public void SendSMS(string phoneNumber, string body)
{
SaveSMSToFile(phoneNumber,body);
}
private void SaveSMSToFile(string mobileNumber, string body)
{
/*implementation for saving SMS to a file*/
Console.WriteLine("Mocking SMS using file to mobile:
{0}. SMS body: {1}", mobileNumber, body);
}
}
we need to implement a change to our (UIHandler) class constructor to pass the dependency through it, by doing this, the code which uses the (UIHandler) can determine which concrete implementation of (ISMSService) to use:
public class UIHandler
{
private readonly ISMSService _SMSService;
public UIHandler(ISMSService SMSService)
{
_SMSService = SMSService;
}
public void SendConfirmationMsg(string mobileNumber) {
_SMSService.SendSMS(mobileNumber, "Your order has been shipped successfully!");
}
}
Now, we have to create a separate class (NinjectBindings) which inherits from (NinjectModule). This class will be responsible to resolve dependencies at run time, then we’ll override the load event which is used to configure the binding in it. The nice thing about Ninject is that we do not need to change our code in (ISMSService), (SMSService), and (MockSMSService).
public class NinjectBindings : Ninject.Modules.NinjectModule
{
public override void Load()
{
Bind<ISMSService>().To<MockSMSService>();
}
}
Now in UI form code, we’ll use the binding for Ninject which will determine which implementation to use:
class Program
{
static void Main(string[] args)
{
IKernel _Kernal = new StandardKernel();
_Kernal.Load(Assembly.GetExecutingAssembly());
ISMSService _SMSService = _Kernal.Get<ISMSService>();
UIHandler _UIHandler = new UIHandler(_SMSService);
_UIHandler.SendConfirmationMsg("96279544480");
Console.ReadLine();
}
}
Now the code is using the Ninject Kernal to resolve all chain of dependencies, if we want to use the real service (SMSService) in Release mode (on production environment) instead of the mock one, we need to change on the Ninject binding class (NinjectBindings) only to use the right implementation or by using the #if DEBUG directive as below:
public class NinjectBindings : Ninject.Modules.NinjectModule
{
public override void Load()
{
#if DEBUG
Bind<ISMSService>().To<MockSMSService>();
#else
Bind<ISMSService>().To<SMSService>();
#endif
}
}
Now our binding class (NinjectBindings) is living on the top of all our execution code and we can control the configuration easily in once place.
Also, see What is Inversion of Control? some very simple examples are mentioned to understand IoC.

You have to understand the Dependency Injection(DI) first. Notice here,
public interface IService
{
void Serve();
}
public class Service1 : IService
{
public void Serve() {
Console.WriteLine("Service1 Called");
}
}
public class Service2 : IService
{
public void Serve() {
Console.WriteLine("Service2 Called");
}
}
public class Service3 : IService
{
public void Serve() {
Console.WriteLine("Service3 Called");
}
}
public class Client
{
private IService service;
public Client(IService _service) //Constructor injection
{
service = _service;
}
public void ServeMethod() {
service.Serve(); //Notice here, this Serve() method has no idea what to do.
} // runtime will assign the object, that is Ninject
}
class Program
{
static void Main(string[] args)
{
IService s1 = new Service1(); //N.B. Ninject assigns object with interface
Client c1 = new Client(s1);
c1.ServeMethod();
IService s2 = new Service2(); //N.B. Ninject assigns object with interface
c1 = new Client(s2);
c1.ServeMethod();
IService s3 = new Service3(); //N.B. Ninject assigns object with interface
c1 = new Client(s3);
c1.ServeMethod();
Console.ReadKey();
}
}
// Ninject creates object in runtime for interface in runtime in ASP.NET MVC project.
/*
Output:
Service1 Called
Service2 Called
Service3 Called
*/

Related

Is there a good way to achieve dependency injection in ASP.NET MVC application without any DI Container?

So I have created the simplest of the applications using ASP.NET MVC (in .NET Framework) and I want to demo dependency injection to a junior using this. it is very simple code, even a newbie can understand it.
public interface IMovieRepository
{
MyViewModel GetDetails(string movie);
}
public class MoviesController : Controller
{
[HttpPost]
public async Task<ActionResult> Search(string movie)
{
// Confusion here! Is the below line a good place to inject dependency
IMovieRepository repository = new DBMovieRepository(); // <-- it can be DBMovieRepository or WebServiceMovieRepository or MockMovieRepository
MovieFinder finder = new MovieFinder(repository);
MyViewModel model = await finder.Find(movie);
return View(model);
}
}
public class MovieFinder
{
private IMovieRepository _repository;
public MovieFinder(IMovieRepository repository)
{
_repository = repository;
}
public async Task<MyViewModel> Find(string movie)
{
// Connect to database and return a detailed object
var myViewModelObj = _repository.GetDetails(movie);
return myViewModelObj;
}
}
public class DBMovieRepository : IMovieRepository
{
public MyViewModel GetDetails()
{
// Code for fetching data from a database
}
}
public class WebServiceMovieRepository : IMovieRepository
{
public MyViewModel GetDetails()
{
// Code for fetching data from a IMDB webservice
}
}
public class MockMovieRepository : IMovieRepository
{
public MyViewModel GetDetails()
{
// Code for returning a mock object here
}
}
There is an inline comment in the code where I asked that my confusion is here. Is that a good place to inject dependencies or do I have to inject it in the MoviesController constructor. If yes, then how will I pass it to the constructor? This is a .NET Framework 4.5 application and I don't want to complicate the lesson by introducing a DI Container and just want to use Pure DI to clarify the concept to my junior.
This is a .NET Framework 4.5 application and I don't want to complicate the lesson by introducing a DI Container and just want to use Pure DI to clarify the concept to my junior.
That literally doesn't make sense.
Pure DI
Or Dependency Injection simply means using IOC to provide an Instance of a Dependency to the object (via Constructor or Property).
Inversion of Control simply means that instead of the dependent object creating the Dependency, you invert control to something else to provide the instance.
You can Architect your Controller to use IOC. You can't DI without something providing the instance. The most lightweight/semi-hacky way to write your DI with minimum effort using your stack is to write your own Controller Factory to inspect your constructor for its dependencies and inject whatever those dependencies are (or just assume what it needs, pass it... yikes).
Relevant SO Question of Mine: My MVC Custom ControllerFactory works but could it be better?

Dependency Injection in ASP.NET MVC

I've been using Dependency Injection in ASP.NET MVC the way I've explained in the below code, but I'm not sure if that is the right and standard way to do it. So I just wanna know if what I'm doing is wrong or if there is a better and more professional way to do it.
public interface IService {
public Boolean AddRecord(Object _Model);
}
public class Employee: IService {
DataBase Context = new DataBase();
public Boolean AddRecord(Object _Model) {
Context.Add((EmployeeModel) _Model);
return Context.SaveChanges() != 0;
}
}
public class DataController: Controller {
IService service;
public DataController(IService service) {
this.service = service;
}
public ActionResult AddRecord(Object _Model, String Caller) {
if (service.Add(_Model)) {
TempData["Result"] = "Data Added";
return RedirectToAction(Caller);
}
TempData["Result"] = "Please try again";
return View (Caller, _Model);
}
}
When I wanna use the controller with the DI, I do: (Is this the right way to consume the DataController)
public class TestController: Controller {
public ActionResult Index () {
return View();
}
public ActionResult TestIt (EmployeeModel _Model) {
DataController DC = new DataController(new Employee());
return DC.AddRecord(_Model, "../Test/TestIt");
}
}
You have the general concept of Dependency Injection / Inversion down. That is, you've understood that instead of this:
public class Example {
public void SomeFunc() {
var service = new Service();
service.DoStuff();
}
}
..you do this:
public class Example {
private readonly IService _service;
public Example(IService service) {
_service = service;
}
public void SomeFunc() {
_service.DoStuff();
}
}
.. and you supply the dependency manually via the calling code.. such as a Controller:
public HomeController : Controller {
[HttpGet]
public ActionResult Index() {
var example = new Example(new Service());
example.SomeFunc();
// .. the rest ..
}
}
So, the first part is Dependency Inversion. You have inverted the dependency chain from being top down to bottom up. The second part (the above code block) is Dependency Injection.
Notice in the above block of code that the Controller has no dependencies injected. This is where Inversion of Control comes in.
Inversion of Control is a pattern where code completely external to the currently running code decides how it functions. In this context, it means some external code - somewhere else - decides how to supply dependencies to your controller.
(Note, I am quite familiar with Ninject - so the below examples are using Ninject. There are plenty of other available DI/IoC containers available)
Ninject is a framework that can help with this (and many others). Ninject has an extension for ASP.NET MVC which automatically builds and supplies controller instances for you - plus your dependencies.
Without providing a full tutorial on using Ninject (which I will leave as an exercise to the OP to Google), the basics of it is this.
You declare a "module" with the configuration for your dependencies. Using the above examples, your module might look like this:
public class YourModule : NinjectModule {
public override void Load() {
Bind<IExample>().To<Example>().InRequestScope();
Bind<IService>().To<Service>().InRequestScope();
}
}
This will wire up all requests for an IExample to an Example, and IService to an instance of a Service. So your Controller would become:
public class HomeController : Controller {
private readonly IExample _example;
public HomeController(IExample example) {
_example = example;
}
[HttpGet]
public ActionResult Index() {
_example.SomeFunc();
// .. the rest ..
}
}
The container (in this case, Ninject) looks at your external code (the YourModule class) and determines what IExample should be. It sees that you've said it should be an instance of an Example class. Example also requires a dependency of type IService. So Ninject will again look at YourModule and determines that it should be an instance of Service. It continues to go down the object hierarchy until it completes the construction of the objects.
Hopefully that makes sense - it is definitely hard to explain these concepts in text.
I haven't viewed this video (I am running off of really really terrible WiFi hotspot while I wait for an internet connection!) so I can't verify it's quality, but a quick Google search turned this up for setting up Ninject and MVC: http://www.youtube.com/watch?v=w_MehI2qBTo
You would definitely benefit from Googling around some Inversion of Control and/or Ninject videos to understand what frameworks like it are for.
It is important to note too that frameworks like Ninject can also control scope. In the example above, I used InRequestScope against the bindings. This means that Ninject will instantiate the dependency at the start of the web request - and dispose of it afterward. This removes the need for you to worry about that.

Autofac WCF Integration - Resolve dependencies based on request data

How can I configure an Autofac container so it resolves the dependencies of a WCF service based on properties values of the operation-parameter (request object)?
For example, given this data contract...
[DataContract]
public class MyRequest
{
[DataMember]
public bool MyBool { get; set; }
}
this WCF service...
public class MyWcfService : IWcfService
{
private IService m_service;
public MyWcfService(IService service)
{
m_service = service;
}
public virtual MyResponse Operation(MyRequest request) { }
}
and these dependencies...
public interface IService { }
public class TypeA : IService { }
public class TypeB : IService { }
I would like the container to resolve TypeA if MyBool equals true and TypeB otherwise. Is that feature available? Should I approach the problem differently?
Constraints:
Avoiding the Autofac.Extras.Multitenant package is a plus.
Keeping the signature of the service constructor unchanged is also desired. (See my answer below)
There are a few ways to achieve this. One of the ways is to use IIndex<K,V>. It's built-in "lookup" feature that chooses between service implementations based on a key. You can find more info on Autofac's wiki page. An example code could look like:
// Register your dependency with a key, for example a bool flag
builder.RegisterType<TypeA>().Keyed<IService>(true);
builder.RegisterType<TypeB>().Keyed<IService>(false);
// Your service could look like:
public class MyWcfService
{
private readonly IIndex<bool, IService> _services;
// Inject IIndex<Key,Value> into the constructor, Autofac will handle it automatically
public MyWcfService(IIndex<bool, IService> services)
{
_services = services;
}
public virtual void Operation(MyRequest request)
{
// Get the service that you need by the key
var service = _services[request.MyBool];
}
}
Another approach is to use Metadata feature. More information on wiki page.
Option 1 - Using Autofac:
The Autofac instance provider that creates your service instance does not use or pass along the operation's message. Here's the latest implementation of the method in Autofac. Notice the message parameter is unused.
public class AutofacInstanceProvider : IInstanceProvider
{
// lots of code removed...
public object GetInstance(InstanceContext instanceContext, Message message)
{
if (instanceContext == null)
{
throw new ArgumentNullException("instanceContext");
}
var extension = new AutofacInstanceContext(_rootLifetimeScope);
instanceContext.Extensions.Add(extension);
return extension.Resolve(_serviceData);
}
}
So to get the behavior you want with existing Autofac code, you'll need to inject the dependency into your class using something other than constructor injection, which is #Alexandr Nikitin's solution. This is reasonable, but I agree with the comment "not loving it".
Option 2 - A Custom IInstanceProvider:
Writing a custom WCF IInstanceProvider is a reasonable option, but it will be a lot of code.
The good news is that the code in Autoface.Integration.WCF is a nice example and you could plug your implementation into Autofac.
The bad news is that Autofac.Integration.WCF code doesn't itself use dependency injection. For example AutofacDependencyInjectionServiceBehavior directly calls var instanceProvider = new AutofacInstanceProvider(_rootLifetimeScope, _serviceData). As a result you'll you have to implement a replacement for AutofacInstanceProvider, AutofacDependencyInjectionServiceBehavior, AutofacHostFactory, and probably more. Then you'll need to create an extension for the AutofacInstanceContext to contain the information read from the message. Its a lot of code.
If you are going to do the custom IInstanceProvider I suggest reading up on Carlos Figueira's blog:
WCF Extensibility – IInstanceProvider - for good background
WCF Extensibility – Message Inspectors - Search for the section that starts with WCF Message objects can only be “consumed once". You'll need to follow these rules when inspecting the message.

Best practice for Ninject to get different implementations based on top level project

I am just starting to learn Dependency Injection and I am stuck here.
My project has a WCF DataService over an Entity Framework DbContext.
public class MyDataService : DataService<MyDbContext>
{
protected override MyDbContext CreateDataSource()
{
// I want to use dependency injection for this
return new MyDbContext();
}
}
The class is either
a) IIS hosted, so I don't have any control
b) for integration tests, created with var host = new DataServiceHost(type, new Uri[] { });
both use different contstructors for MyDbContext
So basically to inject the Context with this
protected override MyDbContext CreateDataSource()
{
INinjectModule module = ???; // -
IKernel kernel = new StandardKernel(module);
return kernel.Get<MyDbContext>();
}
So the question is, what is best practice in this situation?
Should I:
a) Create a Module in a Class Library that both main projects and the service use
b) Create a public static Variable inside the DataService project that holds the Ninject module.
c) Create a public static Variable inside the DataService project that holds the Ninject kernel
d) Something else.
I would prefer something like
protected override MyDbContext CreateDataSource()
{
DefaultKernel.Get<MyDbContext>();
}
Firstly, you should have a Composition Root. That is, a single place where your Kernel is created (not in every single function).
Secondly, you don't need a NinjectModule here.. you're asking Ninject to create an instance of a concrete object (which in almost all circumstances.. defeats the purpose).
What you should create, is a separate NinjectModule pass it into the constructor of the Kernel.. something like this:
interface IContext {
}
class MyDbContext : DbContext, IContext {
}
class YourModule : NinjectModule {
protected override void Bind() {
Bind<IContext>().To<MyDbContext>();
}
}
// In your composition root somewhere
var kernel = new StandardKernel(new NinjectModule[] { new YourModule() });
// in your createdatasource method
kernel.Get<IContext>();
This will get you started. Normally, your composition root is what drives injection of objects throughout your application, thereby eliminating the need to pass the Kernel around (which you will have to do in your current setup).
The hard thing to understand when starting out with DI/IoC is that it is the container's job to create your entire dependency graph. Therefore, if you setup the following bindings:
IContract1 -> ConcreteObject1
IContract2 -> ConcreteObject2
IContract3 -> ConcreteObject3
..and have the following setup:
class ConcreteObject1 : IContract1 {
public ConcreteObject1(IContract2 contract3) {
}
}
class ConcreteObject2 : IContract2 {
public ConcreteObject2(IContract3 contract3) {
}
}
If you ask your container for a concrete implementation of IContract1 (which will be ConcreteObject1), then it will create it.... BUT: ConcreteObject1 requires a concrete implementation of IContract2 in the constructor. So the container says "Wait, I know how to create this".. and passes in an instance of ConcreteObject2. Again, it says "wait, ConcreteObject2 wants a concrete implementation of IContract3.. again, it goes and fetches one.
Hopefully that helps.

Where to keep dictionaries in app using Dependency Injection

I have a legacy code, and I have a problem with reconstructor it.
At start of my application I load from WCF to property on App (this is SL application) list of users.
Then every control (for sending emails, view calendar and assigning tasks) use this property as
(App.Current as App).Users
Now, I'm trying to create Unit Test for one of controls that use this lists, and I'm stuck.
Should I make a Constructor Injection(I'm using Unity) with App as parameter? Or maybe introduce some class to hold this list?
Updated with OP's implementation as the pseudocode was incomplete.
I propose create an interface for all your application services
Inject IApplicationService to your modules.
You can use this interface for all the services the application provides(probably you will need more). Mock the interface for the unit tests
OP's implemantation
public interface IApplicationService
{
List<User> Users{get;set;}
}
public class ApplicationService : IApplicationService
{
public List<User> Users
{
get { return (App.Current as App).Users; }
set { (App.Current as App).Users = value; }
}
}
public partial class MainWindow : UserControl
{
readonly IApplicationService _applicationService
public MainWindow(IApplicationService applicationService)
{
_applicationService=applicationService;
}
}
I would create a wrapper class that will expose the list of users. In production code this class will just be a wrapper around your App.Current property and it can be injected in the constructor trough Unity.
In your Unit Tests you can easily mock the App parameter and pass it when constructing a new SUT.
Something like:
public interface IUserList
{
List<User> Users { get; }
}
public class SUT
{
private IUserList UserList { get; set; }
public SUT(IUserList userList)
{
this.UserList = userList;
}
}
public class AppUserList : IUserList
{
public List<User> Users
{
get
{
return ((App)App.Current).Users;
}
}
}
For Silverlight there is an extension model called Application Extension Services.
For infrastructure purposes that might be a better alternative than adding properties to your app class and casting App.Currentback and forth.
Downside of that model is the creation of a singleton you would have to initialize for your unit tests. It would also hide the dependency on Users in your consuming classes.
Your users seem to be just data. Making that data an ambient context which can be accessed and edited everywhere in your application will bite you. You don't know who does what with that data and when he does it. This is like a session state.
So making the dependency on your data explicit would be a first step to be able to track abuse of that data.
If it makes sense to you to create a "data holder object" that has a property for Users or directly inject that data into your consumers is up to you. If there is more data than just Usersit is tempting to put all of them into the same central data store object, even if your specific consumers don't need them.
Jimmy's answer is great, but can be provide quite a bit, and some errors fixed. Differences are explained at the bottom below the code/instructions:
Create a public interface: IUserService
public interface IUserService
{
// Implemented functionality as methods where possible for better
// extendability (like IoC)
IEnumerable<User> Users();
// Add any other user service stuff as you see fit.
void AddUser(User user);
}
Write a UserService that implements IUserService
public class UserService : IUserService
{
// If you need DI for this service, follow the same pattern of using
// fields and controller injection. I left examples in comment below.
// private readonly IRepository _repository;
// Constructor is unnecessary if you do not need DI example.
public UserService(/* IRepository repository */)
{
// _repository = repository;
}
// Methods
public IEnumerable<User> Users()
{
return ((App)App.Current).Users;
}
public void AddUser(User user)
{
((App)App.Current).Users.Add(user);
}
}
Inject IUserService into classes via their Constructor
In this case your MainWindow as an example:
public partial class MainWindow : UserControl
{
private readonly IUserService _userService;
public MainWindow(IUserService userService)
{
_userService = userService;
}
// Example method consuming the service
public IEnumerable<User> GetUsers()
{
return _userService.Users();
}
}
Differences:
Separate your User Services from a central Application Service
Better modularity. In addition I use an IApplicationService for more central/global data like Api Keys, Timeouts, cleanup, DB prepping, etc.
Return IEnumerable<T> instead of List<T>
This is just a golden rule of thumb for keeping things dry and not imposing hard instantiations on your consuming classes. Refactoring is easier/safer, and your code more extensible.
Use methods instead of properties
This is preference, but I think it smart in a service layer to use methods where possible so that you can introduce filters and overloads or continue to use dependency injection - for example, you could add GetUsers(string lastName), GetUsers(string lastName, string firstName) and maintain a clean interface for your consuming classes.
Cast App.Current without the as keyword
This is a good practice because using the as keyword means when the cast fails it will return null, rather than throw an exception. I prefer the exception because 99% of the time, if your cast fails, your next operations will too. :)
Enjoy!

Categories