Using Castle Windsor for DI, in my MVC controller, I have the following:
public IAccountService AccountService { get; set; }
public IPasswordService PasswordService { get; set; }
public IEmailService EmailService { get; set; }
public AccountController(IAccountService accountService,
IPasswordService passwordService, IEmailService emailService)
{
AccountService = accountService;
PasswordService = passwordService;
EmailService = emailService;
}
The Account service is doing standard auth stuff, the password service is used to reset the users password, and the email service is used to send confirmation emails to the user.
My question is this: am I injecting too many services in this constructor? Is there a significant negative impact of doing this? If so, what is a better approach? Thx.
This is really a matter of opinion, but I don't think many people would have a problem with three injected services.
The rule of thumb that I learned early in my career was that more than five parameters to any method (including constructor methods) is too many. I've since seen arguments that more than three is too many.
Injecting too many services could be a symptom that your class has too many responsibilities, but it might just be a symptom of what those responsibilities are. I would personally never refactor a class for the sole purpose of injecting fewer dependencies, but would definitely see this as a reason to review the code and make sure it wasn't a symptom of some other problem.
As an aside, you should make your setters private (or even better: use a read-only member variable) for the services that are injected--generally you don't want to expose them to change from the outside.
What you have looks completely fine, aside from Phil's comment about making those setters private. In fact, there are many instances, especially with an account controller, where you're going to need a lot more than just 3 services injected.
Where you'd want to exercise caution would be with what you're injecting, and weather or not it belongs directly in the controller in the first place.
Other than that, as long as you're using the design pattern appropriately (which you are), you don't have anything to worry about.
Related
I have a user class in my framework and I want to initial the first time when login.
public class UserClass
{
public void Initial(string userId, string userName)
{
UserId = useriId;
UserName = userName;
}
public string UserId { get; private set; }
public string UserName { get; private set; }
}
I want life this class depend on
HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName]
I'm not sure if your Initial method is meant to be a constructor for UserClass or an init function. You might approach the solution differently depending on that. In either case, there's three ways I'd consider approaching this:
Explicitly (constructor)
Build a wrapper service exposing the values from cookies and make your UserClass consume that. It's the simplest, least magical option that will be easy for anyone on your team to grasp.
DynamicParameters (constructor)
Use the DynamicDependencies feature to pass the cookie values through to the resolution pipeline. It ties you to Windsor and may not be super-obvious to every person on your team so you need to consider that.
OnCreate (init)
Use the OnCreate feature to initialise the object post-construction. Pretty much the same idea as option 2, but used on an already-constructed object. This can work applying either explicit or implicit approach (that is 1. or 2. from above)
Like with everything, it's all a trade-off between what is technically possible and what makes sense for your code architecture and team.
I have an object called StyleBundle.
public class StyleBundle
{
public StylePricingType StylePricingType { get; private set;}
public decimal Price {get; private set;}
public IEnumerable<Style> Styles { get; set;}
public DateTime StartDate {get; private set;}
public TimeSpan Duration {get; private set;}
public bool IsTransient {get; set;}
public void ChangeStylePricingType(StylePricingType newStylePricingType)
{
this.StylePricingType = newStylePricingType;
}
}
This StyleBundle object has a property called StylePricingType. The StylePricingType is an enum of two types:
PerStyle
Unlimited
The StylePricingType will effect the overall Price of the StyleBundle. The way it will affect the Price is by changing the Styles kept in the Styles list. An Unlimited StyleBundle will automatically include all available Styles, but a PerStyle StyleBundle will allow a user to manually pick which Styles they want to include.
I now need to allow the StylePricingType to be changed if the StyleBundle is transient (previous rules stated that once a StyleBundle is new'ed up, you can not change the StylePricingType).
BUT, in order to make this change, I need to run a check against the database via a repository/specification/service... aka, however I want to do it.
The check basically looks for any other StyleBundles during the same duration of the current StyleBundle, and makes sure there are no overlap in Styles in the StyleBundle.
Since changing this property on a transient StyleBundle requires a check against other persisted StyleBundles, what is the best way to go about implementing this?
Use Constructor injection: inject a service into the StyleBundle entity's constructor. I don't like this, b/c I don't like injecting dependencies into my entities unless I need to do so. Also, since I don't like the idea of injecting the dependency into the constructor when it's only needed for the method call that will change the StylePricingType, I see this as bad design.
Use Method injection: Since I would only need the service for this one method call, this seems to make more sense. Yet at the same time, I don't like the idea the user being able to change this type without knowing they're running a db query. Also, I'm still injecting a service into my entity, just in a different way, and I really do not like injecting anything into my entities.
Use a Domain Service: this seems to be the most explicit of all. I could create a StyleBundleService class that has a ChangeStylePricingType method that uses a repository or specification to run the check given a StyleBundle. This way, the requirement is made very explicit in the code, but the drawback here is code could still call the ChangeStylePricingType method directly on the StyleBundle object, and BYPASS the ChangeStylePricingType method on the service I need to make. Even if I set the StylePricingType to get;set; instead of private set; and got rid of the ChangeStylePricingType method on StyleBundle, code could still make the change, bypassing the domain service.
So, these all seem like legitimate ways to go about doing something like this, so what is the best/most accepted way of doing it using DDD? Also, maybe my StyleBundle object is trying to do too much, and should be broken into smaller classes/functionality that would allow this requirement change to be handled more eloquently?
Mike
This is a common issue encountered in DDD. A similar problem is discussed by Udi Dahan in this post. Option 1 is discussed in this question. Option 2 is discussed elsewhere on SO (don't have exact link), but like you, I am not a fan, even though it is the simplest and most direct way. Option 3 is often associated with an anemic domain model, however I often find it to be preferable. The reason is that an encapsulating service layer is something that arises natural as part of DDD - it exposes the domain layer to other layers, such as the presentation layer, or an open host service. Furthermore, actions performed on domain entities can be represented as command objects which are handled by the service. In this case, you can have:
class ChangeStylePricingTypeCommand {
public string StyleBundleId { get; set; }
public StylePricingType StylePricingType { get; set; }
}
class StyleBundleService {
IStyleBundleRepository db;
public void Process(ChangeStylePricingTypeCommand command) {
using (var tx = this.db.BeginTransaction()) {
var bundle = this.db.Get(command.StyleBundleId);
// verification goes here.
bundle.ChangeStylePricingType(command.StylePricingType);
this.db.Commit();
}
}
}
The service StyleBundleService is a perfect place for accessing repositories and other services.
The approach outlined by Udi entails the ChangeStylePricingType raising a domain event, to which would be subscribed a handler, which in turn executes the required business logic. This approach is more decoupled, but is more complex and may be overkill. The other issue with a domain event based approach is that the handler executes after the event happened, and thus cannot prevent it, it can only deal with the consequences.
While I agree it is a good idea to externalize that behavior out of StyleBundle, I usually try to avoid using Services as much as possible. To be more precise, I try to avoid naming something a Service if there are known pattern names that better suit what you really want the object to do.
In your example, it's still unclear to me whether you simply want to check the validity of a StyleBundle against the new StylePricingType you assign to it, rejecting the operation altogether if the bundle doesn't comply, or if you want to adjust the contents of the bundle according to the new StylePricingType.
In the first case a Specification seems best suited for that (you mentioned in the comments you're already using one when adding Styles to a bundle). In the second you need an object that will actually act on the Bundle, eliminating non-compliant styles. I'd use a StyleRuleOutStrategy/Policy with an Enforce() method taking the Bundle as a parameter. In both cases you'd call the relevant method of the new Specification/Strategy in the property setter when changing Specification/Strategy.
Note that the Strategy part takes all its meaning if the action to take is not the same when switching to PerStyle than when switching to Unlimited, but again from what you explained it is not clear this is the case.
I've got a project where we have our own customer registration and account management system, but certain elements of the application link to 3rd party services. These services have common functionality e.g. creating an account in their own DB, but the underlying implementation will be different for how to interactive with the third party services.
What I've done so far is create a CustomerRepository which implements ICustomerRepository. This contains all our own specific requirements. ICustomerRepository also has definitions for the common methods that all third parties will have, but these methods are set to virtual in the CustomerRepository class, which throws exceptions if they're called, requiring you to implement them in the third party classes.
Then from this, I have:
ThirdPartyACustomer : CustomerRepository, IThirdPartyACustomer
ThirdPartyBCustomer : CustomerRepository
As you can probably guess, both of those sub classes inherit and override the virtual methods, with the exception of ThirdPartyACustomer which also implements additional methods that are specific to that particular type of third party user (e.g. there might be a place where the user can edit specific features related to third party A, which third party B doesn't offer.
Now, with that out of the way, the real basis of my question:
Some of the processes (controllers) in my application can use the CustomerRepository without any problems as they only need our core functionality.
Other processes in the app require a particular type of ICustomerRepository to be passed. Anything that calls a method that was defined as virtual in CustomerRepository will need to pass either ThirdPartyACustomer or ThirdPartyBCustomer so that the correct implementation is called.
Originally in this initialisation of this type of controller I'd do something like:
public RegistrationController()
{
ICustomerRepository _customerRepository = GetCustomerRepository();
}
where GetCustomerRepository() had some logic that determined which type of ThirdParty to use, based on the subdomain, for example.
Now, what I'm thinking is that I improve this by creating a custom attribute, along the lines of this:
[ThirdPartyDependent]
class RegistrationController
{
public RegistrationController(ICustomerRepository customerRepository)
{
_customerRepository = customerRepository;
}
}
and move the population of customerRepository parameter into that attribute, e.g. the logic in GetCustomerRepository would happen in there.
I'm fairly sure something like this is doable and seems to make sense for testing purposes, but not quite sure of what I should be googling for, or whether there is a better way to do things, so looking for some guidance from someone more experienced with MVC.
That's the responsibility of your DI framework. For example Ninject provides you access to the HttpContext when configuring the dependencies, so you could pick the proper implementation based on some HttpContext value. For example:
kernel.Bind<ICustomerRepository>().ToMethod(ctx =>
{
if (HttpContext.Current.... Test something on the request or domain or whatever)
{
return new ThirdPartyACustomer();
}
return ThirdPartyBCustomer();
});
and then of course your controller will be totally agnostic. All that a controller should care is that it gets injected some repository which obeys a given contract:
public class RegistrationController: Controller
{
private readonly ICustomerRepository _customerRepository;
public RegistrationController(ICustomerRepository customerRepository)
{
_customerRepository = customerRepository;
}
}
I'm practicing DDD with ASP.NET MVC and come to a situation where my controllers have many dependencies on different services and repositories, and testing becomes very tedious.
In general, I have a service or repository for each aggregate root. Consider a page which will list a customer, along with it's orders and a dropdown of different packages and sellers. All of those types are aggregate roots. For this to work, I need a CustomerService, OrderService, PackageRepository and a UserRepository. Like this:
public class OrderController {
public OrderController(Customerservice customerService,
OrderService orderService, Repository<Package> packageRepository,
Repository<User> userRepository)
{
_customerService = customerService
..
}
}
Imagine the number of dependencies and constructor parameters required to render a more complex view.
Maybe I'm approaching my service layer wrong; I could have a CustomerService which takes care of all this, but my service constructor will then explode. I think I'm violating SRP too much.
I think I'm violating SRP too much.
Bingo.
I find that using a command processing layer makes my applications architecture cleaner and more consistent.
Basically, each service method becomes a command handler class (and the method parameters become a command class), and every query is also its own class.
This won't actually reduce your dependencies - your query will likely still require those same couple of services and repositories to provide the correct data; however, when using an IoC framework like Ninject or Spring it won't matter because they will inject what is needed up the whole chain - and testing should be much easier as a dependency on a specific query is easier to fill and test than a dependency on a service class with many marginally related methods.
Also, now the relationship between the Controller and its dependencies is clear, logic has been removed from the Controller, and the query and command classes are more focused on their individual responsibilities.
Yes, this does cause a bit of an explosion of classes and files. Employing proper Object Oriented Programming will tend to do that. But, frankly, what's easier to find/organize/manage - a function in a file of dozens of other semi-related functions or a single file in a directory of dozens of semi-related files. I think that latter hands down.
Code Better had a blog post recently that nearly matches my preferred way of organizing controllers and commands in an MVC app.
Well you can solve this issue easily by using the RenderAction. Just create separate controllers or introduce child actions in those controllers. Now in the main view call render actions with the required parameters. This will give you a nice composite view.
Why not have a service for this scenario to return a view model for you? That way you only have one dependency in the controller although your service may have the separate dependencies
the book dependency injection in .net suggests introducing "facade services" where you'd group related services together then inject the facade instead if you feel like you have too many constructor parameters.
Update: I finally had some available time, so I ended up finally creating an implementation for what I was talking about in my post below. My implementation is:
public class WindsorServiceFactory : IServiceFactory
{
protected IWindsorContainer _container;
public WindsorServiceFactory(IWindsorContainer windsorContainer)
{
_container = windsorContainer;
}
public ServiceType GetService<ServiceType>() where ServiceType : class
{
// Use windsor to resolve the service class. If the dependency can't be resolved throw an exception
try { return _container.Resolve<ServiceType>(); }
catch (ComponentNotFoundException) { throw new ServiceNotFoundException(typeof(ServiceType)); }
}
}
All that is needed now is to pass my IServiceFactory into my controller constructors, and I am now able to keep my constructors clean while still allowing easy (and flexible) unit tests. More details can be found at my blog blog if you are interested.
I have noticed the same issue creeping up in my MVC app, and your question got me thinking of how I want to handle this. As I'm using a command and query approach (where each action or query is a separate service class) my controllers are already getting out of hand, and will probably be even worse later on.
After thinking about this I think the route I am going to look at going is to create a SerivceFactory class, which would look like:
public class ServiceFactory
{
public ServiceFactory( UserService userService, CustomerService customerService, etc...)
{
// Code to set private service references here
}
public T GetService<T>(Type serviceType) where T : IService
{
// Determine if serviceType is a valid service type,
// and return the instantiated version of that service class
// otherwise throw error
}
}
Note that I wrote this up in Notepad++ off hand so I am pretty sure I got the generics part of the GetService method syntactically wrong , but that's the general idea. So then your controller will end up looking like this:
public class OrderController {
public OrderController(ServiceFactory factory) {
_factory = factory;
}
}
You would then have IoC instantiate your ServiceFactory instance, and everything should work as expected.
The good part about this is that if you realize that you have to use the ProductService class in your controller, you don't have to mess with controller's constructor at all, you only have to just call _factory.GetService() for your intended service in the action method.
Finally, this approach allows you to still mock services out (one of the big reasons for using IoC and passing them straight into the controller's constructor) by just creating a new ServiceFactory in your test code with the mocked services passed in (the rest left as null).
I think this will keep a good balance out the best world of flexibility and testability, and keeps service instantiation in one spot.
After typing this all out I'm actually excited to go home and implement this in my app :)
This time I have a more philosopical question.
Most MVC tutorials/books seem to suggest to restrict the scope of one repository to one aspect of the model and set up multiple repositories to cover all model classes. (E.g.: ProjectRep, UserRep, ImageRep, all mapping onto the same db eventually.)
I can see how that would make unittesting simpler but I can't imagine how this would work in the real world, where most entities have relationships between each other. In the end I always find myself with one gigantic repository class per DB connection and an equally arkward FakeRepository for unittesting.
So, what's your opinion? Should I try harder to seperate out repositories? Does it even matter if the ProductRep refers to data in the UserRep and vice versa via PurchaseHistory? How would the different reps make sure they don't lock each other up when accessing the single db?
Thanks,
Duffy
This works in the real world because there's single engine under the hood of the repositories. This can be ORM like NHibernate or your own solution. This engine knows how to relate objects, lock database, cache requests, etc. But the business code shouldn't know these infrastructure details.
What you effectively do when you end up with one giantic repository is exposing this single engine to the real world instead. Thus you mess your domain code with engine-specific details that are otherwise hidden behind repository interfaces.
S#arp Architecture is a very good illustration of how repositories that Josh talk about are implemented and work. Also read the NHibernate best practices article that explains much of S#arp background.
And frankly, I can't imagine how your giantic repository works in the real world. Because the very idea looks bad and unmaintainable.
I've found that by using generics and an interface, you can avoid having to code many separate repositories. If your domain model is well-factored, you can often navigate object graphs using the domain objects rather than another repository.
public class MyDomainObject : IEntity //IEntity is an arbitrary interface for base ents
{
public int Id { get; set;}
public List<DiffObj> NavigationProp { get; set;}
//... and so on...
}
public interface IRepository<T> where T : IEntity, class, new()
{
void Inert(T entity);
T FindById(int id);
//... and so on
}
The usage is pretty simple, and by using IoC you can completely decouple implementation from the rest of your application:
public class MyBusinessClass
{
private IRepository<SomeDomainObject> _aRepo;
public MyBusinessClass(IREpository<SomeDomainObject> aRepo)
{
_aRepo = aRepo;
}
//...and so on
}
This makes writing unit tests a real snap.