In my interface package i have this following piece of code that runs when the user wants to change some info about a artist:
IArtist artistToChange = ContainerHelper.Container.GetExportedValue<IArtist>();
artistToChange.Load(new Guid("provided guid"));
artistToChange.SomeProperty = newValue;
artistToChange.Update();
Being Artist a entity in my domain it is composed among other stuff by a IUser CreatedBy & IUser LastAlteredBy properties that must be loaded (think of Many-To-One relationship). Each Entity also has its own repository. IArtist has a IArtistRepository the same way IUser has IUserRepository.
My problem is the following: How can I get a instance of a concrete implementation of IUser inside of IArtist.Load() while maintaining IoC (without the concrete implementation of IArtist not knowing about the concrete implementation of IUser)?
(To make things easy let's call of CArtist the concrete implementation of IArtist, and CUser the implementation of IUser.)
With that in mind i though about passing the container to the Entities so they could also request parts, but i dont know if that is a good idea or even a anti-pattern, mainly because im using constructor injection and my constructor for 'CArtist' looks like this:
[ImportingConstructor]
public CArtist(IArtistRepository repository)
{
this.repository = repository;
}
but i cant get the container to inject itself with something like
[ImportingConstructor]
public CArtist(IArtistRepository repository, CompositionContainer container)
{
this.container = container
this.repository = repository;
}
So this is basically it... i'm quite lost here... this turned out to be a cry for help/guidance more than a question on itself...
PS: If any other information is necessary pls ask for it!
Assuming you properly export a concrete IArtist class, you can do the following in your code, and then as long as the dll's are available, when you compose the CArtist class, the IArtist type would get injected into the class. You may be able to even get away with a private variable private IArtist _someArtist; (marked with the import attribute)
public class CArtist : IArtist
{
[ImportingConstructor]
public CArtist(IArtistRepository repository)
{
this.repository = repository;
}
public void Load(Guid guid)
{
this.SomeArtist.DoSomething(guid);
...
}
[Import(typeof(IArtist))]
private IArtist SomeArtist { get; set; }
}
Another approach, would be to, again use a property or var in the class, and import it in the constructor
private IArtist _artist;
[ImportingConstructor]
public CArtist(IArtistRepository repository, IArtist artist)
{
this.repository = repository;
this._artist = artist;
}
Aside from those possible approaches, imho passing the container wouldn't be too big of a problem, it would work and you still maintain the separation, I've seen that done in a few places, but I'm no expert in IoC to know definitively whether it's a good or bad practice.
Related
I develop an C# ASP.NET Core MVC app with a lot of razor pages.
Most of my razor pages use logging, sending e-mails and use multiple dbcontextes.
A lot of class looks like this:
class A : PageModel
{
private readonly ADbContext _context;
private readonly UserManager<ApplicationUser> _userManager;
private readonly IEmailSender _emailSender;
private readonly ILogger<MyModel> _logger;
public UpdateModel(ADbContext context,
UserManager<ApplicationUser> userManager,
IEmailSender emailSender,
ILogger<MyModel> logger)
{
_context = context;
_userManager = userManager;
_emailSender = emailSender;
_logger = logger;
}
}
I have 10+ pages like this.
When I create a page, I have to add these fields. So for a lot of times.
What would be the ideal approach to get rid of lot of field declarations? A base class that inherits every page model that I develop? But this base class would be a really general base class with logging, with Email and with contextes that really not similarly fit to each other.
Is it a good architectural choice to declare these fields every time I declare a class that uses them?
In general, yes, this is just what you do. Your dependencies are being injected, which means you need ivars to hold them and a constructor to accept them. It can feel and seem repetitive, but it's actually a good thing. It makes your class glanceable: you can quickly see what dependencies the class has at a glance.
You can create a base class if you like. However, you should be careful to only include things in your based class that are truly applicable to every derivation. The danger is in adding dependencies that aren't actually needed in all cases, and then now you have a bunch of pages loading dependencies they don't need and don't utilize.
You can also use abstractions to some extent here. For example, if each page depends on a context, but it might be different contexts in different scenarios, you can make the ivar typed as DbContext, instead of your concrete context type, and then you can set it to any valid derivation of DbContext. The same goes for your logger. You'd actually want to inject ILogger<MyPageModel>, but you can make the ivar on the base class just ILogger, which will then accept any logger.
Still, when you start to do this, you make it harder to suss out the dependencies of your classes, so it's a give and take. Personally, I'd only use a base class for shared logic, if any exists. If the only purpose of the base class is to define a particular set of dependencies, it's not worth having.
could it be a good occasion to use Filters instead ? Your filter dependencies could be injected via DI ?
https://www.learnrazorpages.com/razor-pages/filters
You can also simplify some cases of DI by injecting directly at function level where the service is required instead of inject at constructor level by adding '[FromService]' juste above the parameter :
[HttpGet]
public ActionResult OnGetDoSomething([FromServices] IEmailSender emailService)
{
// Do something
}
This way, you won't have to instanciate thoses services if the aren't required.
What about something like this?
class A : BasePage {
public UpdateModel(IServiceProvider provider) : base(provider) {
// here you can access the base properties
}
}
class BasePage : PageModel {
public ADbContext _context { get; set; }
public UserManager<ApplicationUser> _userManager; { get; set; }
public IEmailSender _emailSender; { get; set; }
public ILogger<MyModel> _logger; { get; set; }
public UpdateModel(IServiceProvider provider) : base(provider) {
Context = (ADbContext)provider.GetRequiredService(typeof(ADbContext));
UserManager = (UserManager)provider.GetRequiredService(typeof(UserManager));
EmailSender = (IEmailSender)provider.GetRequiredService(typeof(IEmailSender));
Logger = (ILogger)provider.GetRequiredService(typeof(ILogger));
}
}
I have several Web API controllers in my project. After a lot of redundant code, I've refactored them into the code below, which seemed to be highly reusable. However, I'm suddenly getting the error Make sure that the controller has a parameterless public constructor, which seems to be caused by Ninject not being able to resolve the controller bindings. I'm not sure how to bind them.
My code:
public interface IController<T, TK>
{
DataSourceResult Get(DataSourceRequest request);
T Get(TK id);
HttpResponseMessage Post(T model);
T Put(T model);
TK Delete(TK id);
}
public abstract class BaseController<T, TK> : ApiController, IController<T, TK>
{
private readonly IRepository<T, TK> repository;
public BaseController(IRepository<T, TK> repository)
{
this.repository = repository;
}
/* methods here */
}
public class ReceiptsController : BaseController<ReceiptViewModel, long>
{
public ReceiptsController(IRepository<ReceiptViewModel, long> repository) :
base(repository)
{
}
}
In the ninject RegisterServices method, I've tried the following:
kernel.Bind<IController<OntvangstViewModel, long>>().To<OntvangstenController>();
kernel.Bind<BaseController<OntvangstViewModel, long>>().To<OntvangstenController>();
But neither seem to work. Is my implementation or inheritance wrong? Or should I bind them differently?
There is so much discussion around Repositories that you could read for days. One thing that I could point out to make your code better is this:
public class ReceiptsController : ApiController
{
public ReceiptsController()
{
}
public List<Receipt> Get()
{
List<Receipt> receipts = new List<Receipt>();
using (var context = new DbContext())
{
receipts = context.Receipts.ToList();
}
return View(receipts);
}
}
You don't need a repository. They don't really give you anything in benefits. In fact they remove a lot of the goodness from the DbContext. In my example, you don't have to worry about any injection at all.
Take a close look at DbContext.
It is wrapped in a using. That means, when you are done using the database connection, or your database transactions throw an error then your connection gets disposed of properly. Something that doesn't seem to be happening in your scenario - AFAIK.
Secondly, my example takes less time to write because I haven't written; a controller class, its interface, a generic implementation for a repository, a concrete implementation for a repository. So that's 4 classes that I have circumvented.
IMHO - my way is tonnes easier, less code to write. Safer.
I'm using Repository and UoW pattern. My services look like this:
public class MyService : IService
{
private readonly IUnitOfWork<MyContext> unitOfWork;
private readonly IMyRepository myRepository;
public MyService(IUnitOfWork<MyContext> unitOfWork, IMyRepository myRepository)
{
this.unitOfWork = unitOfWork;
this.myRepository = myRepository;
}
//Methods...
}
Within services, I need to use other entities (for example to check for rights, etc).
Is it recommended to use the relevant repositories in the service or use the services directly?
Also, for each user we have rights (boolean) for each CRUD action. These rights are stored in the database.
Should checking of rights be done at the controller level or at the service level?
My golden rule is:
When you get business logic in your UI create a service, otherwise use
the repository directly.
So if you have this code in the UI:
var user = repos.Get(1);
user.FirstName = txtFirstName.Text;
repos.Save(user);
You are fine in my opinion. But if you instead have something like:
var user = userRepository.Get(1);
var accessChecker = authorizationRepository.GetForUser(id);
if (!accessChecker.MaySendEmail(user))
throw new SecurityException("You may not send emails");
var emailSender = new EmailSenderService();
emailSender.Send(user, txtDestination.Text, txtMessage.Text);
repos.Save(user);
It's likely that you should use a service instead.
Don't use your UoW to just wrap your database context. Since all your repositories are directly dependent of a given context (more or less, ofc), your repositories can be included in the UoW. Something along the lines of:
public interface IUnitOfWork<TContext> : IDisposable { }
public abstract class UnitOfWork<TContext> : IUnitOfWork<TContext> {
private readonly TContext _context;
protected TContext Context { get{ return _context; } }
protected UnitOfWork(TContext context){
_context = context;
}
}
public interface IMyDbUnitOfWork : IUnitOfWork<MyContext>{
public ICarRepository Cars { get; }
public IOwnerRepository Owners { get; }
}
public class MyDbUnitOfWork : UnitOfWork<MyContext>, IMyDbUnitOfWork{
public MyDbUnitOfWork():base(new MyContext()){}
private ICarRepository _cars;
public ICarRepository Cars {
get{
return _cars ?? (_cars = new CarRepository(Context));
}
}
private ICarRepository _owners;
public IOwnerRepository Owners {
get{
return _owners ?? (_owners = new OwnerRepository(Context));
}
}
}
public class MyService : IService
{
private readonly IMyDbUnitOfWork _unitOfWork;
public MyService(IMyDbUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
//Methods...
}
Obviously you can create this more or less generic, but I believe this should be enough to pass my point.
As a note, and since I normally use IoC frameworks, my services receive an IUnitOfWorkFactory because of the diferent lifestyles.
For the permissions question, it really depends how much control you want to have and how user friendly you want your application to be. Normally is a mix of both. Your application should know if your user has access to the screen but also if you must disable buttons accordingly. Since you also must prevent that, if by any reason, the user can invoke your service method, you can't allow it.
To solve this problem I don't filter by CRUD actions but by Service actions instead, intercepting every service invocation, which makes it easy to map my permissions to the user interface since normally is a 1 to 1 relation between button action and service action.
I think using repositories is just fine. I wouldn't invent a service layer for each of the repos.
Repository is used for abstracting the data access and service layer is to encapsulate business logic, however with recent trend , I find this overkill. Having service layer is fine if they act as controllers but don't try to map one to one to each entity or repo.
I typically use services from the UI and those services in turn use the repositories. I also find it useful to have some domain objects that encapsulate reusable logic in the services.
I do this so that rather than services calling each other and getting circular references, services use a common domain object instead. This avoids circular references and people copying and pasting the same code all over the place.This domain object may then use the repositories if necessary.
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
*/
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!