As I understand IoC-container is helpful in creation of application-level objects like services and factories. But domain-level objects should be created manually.
Spring's manual tells us: "Typically one does not configure fine-grained domain objects in the container, because it is usually the responsibility of DAOs and business logic to create/load domain objects."
Well. But what if my domain "fine-grained" object depends on some application-level object.
For example I have an UserViewer(User user, UserConstants constants) class.
There user is domain object which cannot be injected, but UserViewer also needs UserConstants which is high-level object injected by IoC-container.
I want to inject UserConstants from the IoC-container, but I also need a transient runtime parameter User here.
What is wrong with the design?
Thanks in advance!
UPDATE
It seems I was not precise enough with my question. What I really need is an example how to do this:
create instance of class UserViewer(User user, UserService service), where user is passed as the parameter and service is injected from IoC.
If I inject UserViewer viewer then how do I pass user to it?
If I create UserViewer viewer manually then how do I pass service to it?
there's nothing wrong with this design. you use Factories for that, which have one leg in the domain, one leg in infrastructure.
You can either write them manually, or have the container do that for you, by things like TypedFactoryFacility in Windsor.
Also when your domain objects come from persistence layer you can plug your container there to inject the services they require (NHibernate can do that).
But what if my domain "fine-grained" object depends on some application-level object?
It is precisely this that is considered bad-practice. I would say the problems could be:
There are tons of these objects, so there can be performance and memory issues.
The POJO style is that they can be used in all environments (persisted in the database, processed in business algorithms and rules, read and set in view technologies, serialized and send over the network). Injecting application-level objects in them could cause the following problems:
In your architecture, you probably have the rule that some (most) application-level objects are usable in some layers, not in others. Because all layers have access to the pojos, the rule would be violated transitively.
When serialized and rebuild in another JVM, what would be the meaning of your application-level objects. They are useless, they must be changed for the local equivalents...
Typically, the pojos that constitute your domain are self-contained. They can have access to other pojos (and many enums), that's all.
In addition to the data, they have methods that implement the details of the business rules or algorithms (remember the OO idea of grouping data and code that work on it ;-) ):
This is especially good when they have inheritance, as this allow to customize a business rule for some pojo by providing a different implementation (differing case without if or switch: remember OO? ;-) ).
Any code that requires access to application-level objects (like accessing the database) is taken out, for example to a Service or Manager. But that code stays high level, thus readable and simple, because the pojos themselves take care of the low level details (and the special cases).
After the fact, you often find out that the pojo methods get reused a lot, and composed in different ways by the Services or Managers. That's a big win on reducing duplication, the methods names provide much needed "meaning", and provide an easier access to developers that are new to a module.
For your update:
create instance of class UserViewer(User user, UserService service), where user is passed as the parameter and service is injected from IoC.
If I inject UserViewer viewer then how do I pass user to it?
If I create UserViewer viewer manually then how do I pass service to it?
In that case, you need a factory method (possibly on a Factory or Locator of yours). It could look at follow, separating the two parts:
public UserViewer createUserViewer(User user) {
UserViewer viewer = instantiateBean(UserViewer.class);
viewer.setUser(user);
return viewer;
}
private <E> E instantiateBean(Class<E> clazz) {
// call the IoC container to create and inject a bean
}
Related
I've read a lot on the subject of IoC containers and particularly Mark Seemann's blog posts, where he emphasises the importance of convention over configuration. I understand and agree with his point, but I wonder how best to mark out a class for an irregular lifetime?
For example, most of my services are registered with a Transient lifetime - but I want a particular service to be registered as a Singleton because it does some useful caching.
I have thought about using some custom attributes, but I have read arguments against this (because it puts composition logic in the class).
I have had this same debate with, for example, dependencies on configuration primitives. Ultimately I ended up using a parameter attribute because it worked in my case, but I feel that perhaps I didn't see the 'hidden dangers'.
It is common for an IoC container to allow you to specify the lifestyle of an object. SimpleInjector, for example, provides Transient and Singleton out of the box (and also allows the user to create a custom lifestyle class). With SimpleInjector it's as simple as:
container.Register<ISvc, Impl>(Lifestyle.Singleton);
or
container.Register<ISvc, Impl>(Lifestyle.Transient);
No need for polluting your classes with composition logic.
As for configuration primitives, a common practice is to put those behind an interface. I put my connection string behind an IDatabaseConfiguration interface, for example, and its implementation reads the value from web.config. I then inject that interface into my data services.
EDIT: Disregard above. Keeping it in so that comments make sense.
The following doesn't actually answer the question, but it may solve the problem that prompted the question. You said that the class does some useful caching, which clues me in on that it is taking on an additional responsibility. I would therefore recommend that you do not attempt to register that single implementation as a singleton, but instead create a decorator class around that implementation.
container.RegisterDecorator(
typeof(ICommandHandler<>),
typeof(CommandHandlerCacheDecorator<>),
Lifestyle.Transient,
x => { return /*some logic that looks for and
finds that one class you want
to decorate*/
});
The decorator needs to be a transient, because it will have a transient reference to the command it decorates. However, it could then access a separate singleton class (via dependency injection of course) or cache object that handles the actual caching.
EDIT: Examples to single out the one class to decorate. There are plenty of options depending on just how specific you want to be. Again this is with SimpleInjector, but I'm sure other containers have their own analogues.
//decorate a specific class
x => { return x.ImplementationType.FullName == "My.Commands.Web.SomeName"; }
//decorate all classes that share a certain namespace
x => { return x.ImplementationType.Namespace.EndsWith("Commands.Web"); }
//decorate all classes that implement the same interface
x => { return x.ImplementationType.IsInstanceOfType(typeof(ICouldCache)); }
Our domain model is very anemic right now. Our entities are mostly empty shells, almost purely designed for holding values and navigating to collections.
We are using EF 4.1 code-first ORM, and the design so far has been to shield our novice developers against the dreaded "LINQ to Entities cannot translate blablabla to a store expression" exception when querying against the context during early iterations.
We have various aggregate root repository interfaces over EF. However some blocks of code in the impls seems like they should be the domain's responsibility. As long as the repository interface is declared in the domain, and the impl is in the infrastructure (dependency injected), is it considered bad design to pass a repository interface as an argument to a method on an entity (or other domain) class?
For example, would this be bad?
public class EntityAbc {
public void SaveTo(IEntityAbcRepository repos) {...}
public void DeleteFrom(IEntityAbcRepository repos) {...}
}
What if a particular entity needed access to other aggregate root repositories? Would this be ok or not, and why?
public void Save() {
var abcRepos = DependencyInjector.Current.GetService<IEntityAbcRepository>();
var xyzRepos = DependencyInjector.Current.GetService<IEntityXyzRepository>();
// work with repositories
}
Update 1
I did not mention moving code to an application layer because I consider some of the code that uses IEntityAbcRepository to involve business rule enforcement. The repository impl should be as vanilla as possible, right? Its main responsibility should just be a simple abstraction over the ORM, allowing you to find / add / update / delete entities. Wrong?
Also, this question applies to methods on other non-entity domain classes -- factories, services, whatever pattern may be appropriate. Point being, I'm asking the question about any method on a domain class, not just an entity class. #Eranga, this is one place where you can use constructor injection because factories & services are not part of the ORM.
The application layer could then coordinate flow by injecting a repository impl into its constructor, and passing it as an argument to a domain service or factory. Is this bad practice?
Update 2
Adding another clarification here. What if the domain only needs access to the IEntityAbcRepository in order to execute its Find() method(s)? In the example above, the SaveTo and DeleteFrom methods would not invoke any add / update / delete methods on the repository interface.
So far we've combined the find / add / update / delete methods on a single aggregate root repository interface for simplicity. But I suppose there's nothing stopping us from separating them out into 2 interfaces, like so:
IEntityAbcReadRepository <-- defines all find method signatures
IEntityAbcWriteRepository <-- defines all add / update / delete method sigs
In this case, would it be bad practice to pass IEntityAbcReadRepository as a parameter to a domain method?
Your first approach is better compared to the second approach which uses "Service Locator" pattern. Dependencies are more obvious in the first approach.
Here are some links that explains why "Service Locator" is a bad choice
Is it bad to use servicelocation instead of constructor injection
...
Singleton Vs ServiceLocator
Say no to ServiceLocator
Both of these solutions stem from the fact that EF does not allow you to use constructor injection. However you can use property injection as explained in this answer. But that does not guarantee that mandatory dependencies are present.
So your first approach is the better solution.
Short answer: Yes!
Long answer:
Consider creating an AbcService in your application service layer. This service layer sits between your domain and your infrastructure. You can inject as many repositories into AbcService as you want. Then let the service handle SaveTo and DeleteFrom.
SaveTo and DeleteFrom, unless you are saving to and deleting from another entity, i.e. no data access is involved, are methods that sound like they shouldn't be on a domain entity, IMO.
Having persistence logic in your domain entities is IMO bad design in the first place. Good separation of concerns should mean that domain/business logic is separated from persistence logic, so your domain classes should be persistence ignorant.
Previous Entity Framwork versions might not have allowed such a separation but I think most recent versions solved that problem. I'm not that familiar with EF though, so I might be wrong.
With that said, where can you put methods such as Save() and Delete() ?
If you want to add to/remove your entity from its repository, Repository.Add() and Repository.Remove() are good choices. A repository basically serves as an illusion of an in-memory collection of your entities, so it makes sense for it to behave just like a collection or a list with the appropriate methods.
If you want to persist changes made to an existing entity, there are other ways to do that. You could have a Repository.Save() method but some consider it bad practice. Oftentimes the changes are part of a higher level operation handled in a transaction-like context such as a Unit of Work, in that case you can let the operation persist all the objects in its scope when it finishes. For instance, if you use an Open Session in View approach for your web application, changes are automatically persisted when the request ends.
Or you can rely on an ad-hoc call of your ORM's Save() method for your particular entity which hopefully shouldn't be grafted onto the entity code itself (with NHibernate, for instance, it's available at runtime on the proxied entity).
[Update]
Putting that in perspective with your subsequent questions (though I'm not sure I understand all of them well) :
I see no value in splitting your repository into a ReadRepository and a WriteRepository. In DDD, a repository's responsibility is clearly to provide a collection to query from as well as add to or remove from. It's still quite cohesive that way.
It's not an entity's responsibility to fiddle with its own persistence, so it shouldn't be aware of its own repository for that precise purpose. Otherwise, it's pretty rare that an entity rightfully needs to have knowledge of its own repository (usually it means that the entity has a relationship to another entity of the same type, like parent/child, and you want to get the other entity from the repository)
However, entities and other domain objects obviously do need to obtain references to other entities at times. In that case, try to get these references through traversal of other objects within the boundary of your aggregate first before looking for a repository. If you absolutely need a repository to get the object you want, it's a good idea to inject the repository through any flavour of injection you like. As Eranga pointed out, service locator might turn out to be a sub-par dependency injection ersatz though.
Last thing, the kind of injection you mentioned - SaveTo(IEntityAbcRepository repos) - is peculiar because it is neither constructor nor setter injection, but rather an ephemeral injection lasting just the time of a method. It implies that whoever calls your method must know what repository to pass at that precise moment, which is not obvious. It might be useful, but I'd say it's not the form of injection you would typically mainly use.
I understand the concept behind DI, but I'm just learning what different IoC containers can do. It seems that most people advocate using IoC containers to wire up stateless services, but what about using them for stateful objects like entities?
Whether it's right or wrong, I normally stuff my entities with behavior, even if that behavior requires an outside class. Example:
public class Order : IOrder
{
private string _ShipAddress;
private IShipQuoter _ShipQuoter;
public Order(IOrderData OrderData, IShipQuoter ShipQuoter)
{
// OrderData comes from a repository and has the data needed
// to construct order
_ShipAddress = OrderData.ShipAddress; // etc.
_ShipQuoter = ShipQuoter;
}
private decimal GetShippingRate()
{
return _ShipQuoter.GetRate(this);
}
}
As you can see, the dependencies are Constructor Injected. Now for a couple of questions.
Is it considered bad practice to have your entities depend on outside classes such as the ShipQuoter? Eliminating these dependencies seems to lead me towards an anemic domain, if I understand the definition correctly.
Is it bad practice to use an IoC container to resolve these dependencies and construct an entity when needed? Is it possible to do this?
Thanks for any insight.
The first question is the most difficult to answer. Is it bad practice to have Entities depend on outside classes? It's certainly not the most common thing to do.
If, for example, you inject a Repository into your Entities you effectively have an implementation of the Active Record pattern. Some people like this pattern for the convenience it provides, while others (like me) consider it a code smell or anti-pattern because it violates the Single Responsibility Principle (SRP).
You could argue that injecting other dependencies into Entities would pull you in the same direction (away from SRP). On the other hand you are certainly correct that if you don't do this, the pull is towards an Anemic Domain Model.
I struggled with all of this for a long time until I came across Greg Young's (abandonded) paper on DDDD where he explains why the stereotypical n-tier/n-layer architecture will always be CRUDy (and thus rather anemic).
Moving our focus to modeling Domain objects as Commands and Events instead of Nouns seems to enable us to build a proper object-oriented domain model.
The second question is easier to answer. You can always use an Abstract Factory to create instances at run-time. With Castle Windsor you can even use the Typed Factory Facility, relieving you of the burden of implementing the factories manually.
I know this is an old post but wanted to add. The domain entity should not persist itself even if you pass in an abstracted repository in ctor. The reason I am suggestion this is not merely that it violates SRP, it also contrary to DDD's aggregation. Let me explain, DDD is suited for complex apps with inherently deep graphs, therefore, we use aggregate or composite roots to persist changes to the underlying "children", so when we inject persistence into the individual children we violate the relationship children have to the composite or aggregate root that should be "in charge" of the life cycle or aggregation. Of course the composite root or aggregate does not persist it's own graph either. Another is with injecting dependencies of DDD objects is that an injected domain object effectively has no state until some other event takes place to hydrate its state. ANy consumer of the code will be forced to init or setup the domain object first before they can invoke business behavior which violates encapsulation.
I'm new to this IoC and DI business- I feel like I get the concept if you are passing along objects that are of a global scope, but I don't get how it works when you need to pass around an object that is of a specific logical state. So, for instance, if I wanted to inject a person object into a write file command object- how would I be able to choose the correct person object dynamically? From what I have seen, I could default construct the object, but my disconnect is that you wouldn't use a default person object, it would need to be dynamic. I assume that the IoC container may just maintain the state of the object for you as it gets passed around, but then that assuems you are dealing in only one person object because there would be no thread safety, right? I know I am missing something, (maybe something like a factoryclass), but I need a little more information about how that would work.
Well, you can always inject an Abstract Factory into your consumer and use it to create the locally scoped objects.
This is sometimes necessary. See these examples:
MVC, DI (dependency injection) and creating Model instance from Controller
Is there a pattern for initializing objects created via a DI container
Can't combine Factory / DI
However, in general we tend to not use DI for Entities, but mostly for Services. Instead, Entities are usually created through some sort of Repository.
When you construct an service object (e.g. WriteFileService), you inject into it things it needs internally to complete it's job. Perhaps it needs a filesystem object or something.
The Person object in your example should be passed to the service object as a parameter to a method call. e.g. writeFileService.write(person)
I've used a fair amount of dependency injection, but I'd like to get input on how to handle information from the user at runtime.
I have a class that connects to a com port. I allow the user to select the com port number. Right now, I have that com port parameter as a constructor argument. The reasoning being that the class cannot function without that information, and it's implementation specific (a mock version of this class wouldn't need a com port).
The alternative is to have a "Start" method that takes in the com port, or have a property that sets the com port. This makes it very compatible with an IoC container, but it doesn't necessarily make sense from the perspective of the class.
It seems like the logical route conflicts with the dependency injection design, but it's because my UI is getting information for a specific type of class.
Other alternatives would include using an IoC container that lets me pass in additional constructor parameters, or just constructing the classes I need at the top level without using dependency injection.
Is there a generally accepted standard pattern for this type of problem?
There are two routes you can take, depending on your needs.
1. Wire the UI directly to your concrete classes
This is the simplest option, but many times perfectly acceptable. While you may have a Domain Model with lots of interfaces and use of DI, the UI constitutes the Composition Root of the object graphs, and you could simply wire up your concrete class here, including your required port number parameter.
The upside is that this approach is simple and easy to understand and implement.
The downside is that you get less flexibility. You will not be able to arbitrarily replace one implementation with another (but then again, you may not need that flexibility).
Even with the UI locked to a concrete implementation, this doesn't mean that the Domain Model itself wouldn't be reusable in other applications.
2. Add an Abstract Factory
The other option is to add another layer of indirection. Instead of having your UI create the class directly, it could use an Abstract Factory to create the instance.
The factory's Create method could take the port number as an input, so this abstraction belongs best in a UI sub-layer.
public abstract class MyFactory
{
public abstract IMyInterface Create(int portNumber);
}
You could then have your DI container wire up an implementation of this factory that uses the port number and passes it as a constructor argument to your real implementation. Other factory implementations may simply ignore the parameter.
The advantage of this approach is that you don't pollute your API (or your concrete implementations), and you still have the flexibility that programming to interfaces give you.
The disadvantage is that it adds yet another layer of indirection.
Most IoC containers have some form of Constructor Injection that would allow your IoC container to pass a mocked COM port into your class for unit testing. That seems like the most clean solution.
I would avoid adding a "Start" method, etc. Its much better practice to (when possible) always have your classes in a valid state, and switching to a parameterless constructor with a start method leaves your class invalid between those calls. Doing this to enable testing is just making your class more difficult in order to test (which should make it nicer).