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.
Related
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.
I have a StructureMap config that looks something like:
cfg.For<ICacheOrder>().Use<CacheOrder>().Ctor<int>().Is(context => LoginHelper.LoginID);
cfg.For<ICacheProduct>().Use<CacheProduct>().Ctor<int>().Is(context => LoginHelper.LoginID);
cfg.For<ISQLOrder>().Use<SQLOrder>().Ctor<int>().Is(context => LoginHelper.LoginID);
cfg.For<ISQLProduct>().Use<SQLProduct>().Ctor<int>().Is(context => LoginHelper.LoginID);
Via constructor injection, a chain of objects can be created, with some needing an int LoginID that is determined at the time of creation. The static LoginHelper determines the LoginID.
Presently in my config, LoginHelper is called for every created object. Is there a way, perhaps via StructureMap's IContext, for LoginID to be "remembered" and only determined once within a chain of creation?
I know that I could refactor and create an ILogin interface/concrete that StructureMap could construct and cache - but I'd prefer my various layers to be concerned only with a simple int LoginID.
Although it's okay to inject primitive configuration values in your services, when you repetitively inject that same primitive into multiple services, you are missing an abstraction.
This is clearly the case with your configuration; you are missing an abstraction.
The solution is to let those services depend on an abstraction rather than a primitive value. For instance:
public interface ICurrentUser
{
int LoginID { get; }
}
And you can create a rather simple implementation as follows:
public class CurrentUserImpl : ICurrentUser
{
public CurrentUserImpl()
{
this.LoginID = LoginHelper.LoginID;
}
public int LoginID { get; private set; }
}
This means that you will have to change the constructors of CacheOrder, CacheProduct, SQLOrder and SQLProduct, but when you do this, your configuration gets much more maintainable:
cfg.For<ICacheOrder>().Use<CacheOrder>();
cfg.For<ICacheProduct>().Use<CacheProduct>();
cfg.For<ISQLOrder>().Use<SQLOrder>();
cfg.For<ISQLProduct>().Use<SQLProduct>();
The problem of "remembering a param literal" now goes away immediately, because we can now register the ICurrentUser as follows:
cfg.For<ICurrentUser>().Use<CurrentUserImpl>();
The default lifecycle in Structure Map is per request (per object graph) so the same instance is injected into all objects in a single object graph.
Another option is to register it using the HttpContext lifecycle, but this of course only works when running an ASP.NET web application.
Consider the following business entity class. In order to validate itself, it needs to know something about the state of the database, perhaps to prevent a conflict of some kind. So, it has a dependency on the data access layer in order to retrieve this data.
Is it a violation of the Single Responsibility Principle to have a class that encapsulates state, validates the state, and accesses a data store to do so?
class MyBusinessObject
{
private readonly IDataStore DataStore;
public MyBusinessObject(IDataStore dataStore)
{
this.DataStore = dataStore;
}
public virtual int? Id { get; protected set; }
public virtual string Name { get; set; }
// ... Other properties...
public IEnumerable<ValidationResult> Validate()
{
var data = this.DataStore.GetDataThatInfluencesValidation();
return this.ValidateUsing(data);
}
// ... ValidateUsing method would be in here somewhere ...
}
It's throwing a red flag for me because:
In the context of an ASP.NET MVC controller's Create method, I might make a new instance and pass it to my View() method with no intention of validating, so why should I be required to pass in an IDataStore?
I'm using NHibernate (and I'm a noob), and it looks like I have to create an IInterceptor that injects dependencies whenever NH creates entities. Maybe that will be fine, but it feels a little bit wrong to me.
I'm starting to think I should use an anemic/DTO type of object for NHibernate to use, and wrap that inside something else that knows all the business rules AND can access a data store if it depends on one. Now that I've typed up my question and title, StackOverflow has suggested some interesting resources: here and here.
My question also looks very similar to this one, but I thought I'd ask it in a different way that more closely matches my situation.
"Is it a violation of the Single Responsibility Principle to have a class that encapsulates state, validates the state, and accesses a data store to do so?" -- You listed three responsibilities so I'm going to answer yes.
The difficulty with validation is that it depends on context. For example, creating a customer record might require just their name but selling them a product requires payment information and a shipping address.
IN MVC, I do low level (data sizes and nullability) validation using data annotations in view models. More complex validation is done using the specification pattern. The specification pattern is easy to implement and flexible.
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.
Question
How do you handle read-only fields when creating fakes?
Background
I'm in the beginner stages of using ASP.Net MVC and am using Steven Sanderson's Sports Store and Scott Gu's Nerd Dinner as examples. One small problem that I've just hit is how to work with read-only properties when doing fakes. I'm using LINQToSQL.
My interface is:
public interface IPersonRespository
{
Person GetPerson(int id);
}
and my fake becomes
public class FakePersonRepository
{
public Person GetPerson(int id)
{
return new Person {id="EMP12345", name="John Doe", age=47, ssn=123-45-6789, totalDrWhoEpisodesWatched=42};
}
}
Here's my problem. The fields id, ssn and totalDrWhoEpisodesWatched are read-only, so the above code won't actually work. However, I don't recognize how to create a fake new person and set a read-only property. I'm sure there is a solution, but I haven't come across it yet in my searches.
Update: Inheritance + Property Hiding as a Potential Solution?
I haven't yet decided upon a firm solution to the problem. I dislike the notion of modifying my Domain classes for the purposes of creating fakes. To me, adding markup to the domain classes in order to do testing is a form of added coupling -- coupling to the implementation of your test. I'm now investigating another possibility, which is to create a FakePerson class, which inherits from Person, but hides the properties with new read-write properties.
public class FakePerson: Person
{
public new int age { get; set; }
public new string ssn { get; set; }
public new int totalDrWhoEpisodesWatched { get; set; }
}
So far, this solution is how I am leaning. It does break the Liskov Substitution Principle, however that doesn't bug me as much in a test project. I'd be glad to hear any criticism and/or feedback on this as a solution.
Winner: Mock Frameworks
Moq appears to do the job. My last solution of hiding the property through inheritance does, in fact, work, however by using Moq, I get a standardized set of functionality that is more maintainable. I assume that other mock frameworks have this functionality, but I haven't checked. Moq is said to be more straightforward for the beginning mock writing, which I definitely am right now.
Consider mocking the Person type in your test. Example using Moq:
var mock = new Mock<Person>();
mock.SetupGet(p => p.id).Returns("EMP12345");
mock.SetupGet(p => p.ssn).Returns("123-45-6789");
mock.SetupGet(p => p.totalDrWhoEpisodesWatched).Returns(42);
return mock.Object;
Otherwise, try finding out how LINQ to SQL sets those read only properties.
EDIT: If you attempt the above and Moq throws an ArgumentException in the SetupGet call with the message "Invalid setup on a non-overridable member: p => p.id", then you need to mark the property as virtual. This will need to be done for each property whose getter you wish to override.
In LINQ to SQL, this can be done in the OR designer by selecting the property, then in the Properties window set Inheritance Modifier to virtual.
You can only set readonly properties in the constructor of the class. The Person object should have a constructor that accepts id, ssn, and totalDrWhoEpisodesWatched. Of course, if this is a linqtosql generated object, you might have issues modifying that as the code is auto-generated.
You could consider using a mapped object to expose in your repository ... so you'd never actually have to use your linqtosql object as your model.
In .NET, you could mark your setters as "internal" and use the InternalsVisibleTo assembly attribute to make internals visible to your test assembly. That way your setters won't be public, but you can still access them.
note: even though the question isn't tagged .NET, I assumed it was based on your usage of object initializer syntax. If my assumption was wrong, this suggestion does not apply (unless the language you're using has an equivalent feature, of course).
If it's for tests - consider using reflection. That wouldn't involve messing around your domain model.
For example - i got FactoryBase class, which uses reflection to set needed prop by lambda expression through parameters (like this). Works like a charm - creating new factory is simple as defining repository type and default entity data.
I also use Moq. I love it and it works great. But, before I started using Moq, I wrote many fakes. Here's how I would have solved the problem using fakes.
Since a fake can have additional methods that the "production" implementation doesn't have, I would add a few extra methods to my fake implementation to handle setting the read-only portion.
Like this:
public class FakePersonRepository : IPersonRespository
{
private IDictionary<int, Person> _people = new Dictionary<int, Person>();
public Person GetPerson(int id) // Interface Implementation
{
return _people(id);
}
public void SetPerson(int id, Person person) // Not part of interface
{
_people.Add(id, person);
}
}