Grails: Services VS Groovy classes - grails

Documentation says:
The Grails team discourages the
embedding of core application logic
inside controllers, as it does not
promote re-use and a clean separation
of concerns.
I have one API controller and a few Groovy classes in src/groovy folder. Those classes just implements my application logic so actions in API controller works in this way:
//index page
def index = {
render new IndexApi().index(params) as JSON
}
I'm curious - is there any reason to move my application logic from plain groovy classes into services ?

Actually services are not just about transactions. Services are great for zero-config injectable singleton components, and they can can be reloaded without restarting the whole grails environment, AND they can be discovered as artefacts and hence automatically exposed with remoting plugins.

If you want transactional behavior you should put your logic in the Services. Else you would have to take care about it yourself, which is not in the spirit of using Grails.
Being not a grails expert myself, I put my 'not transactional' classes outside the service layer, like builder classes, helpers, and other logic that is not transactional but used from the service layer.

There are three reasons:
It makes the controller smaller -> easier to understand and maintain
It makes you logic easier to test.
You really don't want to manage your transactions manually.
If you would put everything in the controller, you would need to create the Web runtime to be able to run any test. If your logic is outside, you can copy the data you need from the HTTP request and all the other sources and just call the code. So the logic isn't depending on HTTP sessions, requests or anything else you don't want to.
For example, to test JSPs, you need a HTTPRequest. For a request, you need a HTTPSession and a JSPWriter. Those need a session context. So just to be able to run a single test, you need to set up and initialize a whole bunch of classes. And all of those are interfaces and the implementations are private. So you must implement the actual methods (all 300 of them) yourself. And you better get this right or your tests won't test what you want.

Related

Replacement for Dependency Injection Container in Rails

I have read dozens of articles about this and still have some questions.
How are services used in multiple parts of the system? For example, I have a permissions component that is used by several other classes during a request. Right now, I have made it a singleton. I have been using singletons as the entry point to portions of my domain (various services) that need to be reused during a request. This seems to be the only way I can access these services in different parts of the system without reinstantiating them or without throwing them in a global variable. In other systems, I would make it a normal class and set it's lifecycle to "request". The container would make sure that it is shared within the request and release it for garbage collection.
I have thought about using a service locator which stores services in Thread.current. But this feels like I'm getting desperate.
The main way I've seen that people accessing these dependencies is to wrap the dependency in a method:
class A
def some_dep
SomeService.instance
end
end
In tests, some_dep is overridden to return a mock or whatever. This seems like the best so far but still feels hackish.
My options for using services within a request seem to be:
1) Put them in a global variable / Thread.current.
2) Use a service locater.
3) Pass dependencies around manually (complete disaster).
4) Singleton.
Two questions:
1) What is the best approach for making services available to multiple parts of the system without reinstantiating?
2) What is the best approach for a class to manage those dependencies?
Note:
I understand that I can put reusable functionality into modules. IMO, however, modules are great for purposes of staying DRY but not for carrying state around the system (i.e. which tenant you're on in a multitenant application).

What are the next steps for unit testing with dependency injection?

I'll start out by saying I'm a huge fan of unit testing. I've been using it for a couple of years. So far, though, my use has been limited to ensuring engineering calculations are performed correctly, strings are formatted properly, etc. Basically, testing my work on class libraries to be consumed in other projects.
Now, I want to branch out and apply unit testing to my work on ASP.NET Web API. At this point I have my controller written and working with Ninject. Although I'm using Ninject, I'm still not 100% sure why I'm doing it and haven't seen the benefits yet.
On to my question, what are the next steps for unit testing my Web API controllers? What should I do next and when will I reap the benefit of using Ninject?
Next, you could create fake data (or a mock) that your controller can return to your views. This will allow you to do front end development without having to complete the back end implementation.
The benefit of using Ninject is that you can create mock objects for testing purposes. By injecting the interface instead of the concrete implementation you can easily switch between the real and mock object. To do this you simply change which one should be injected in the Ninject bindings. Using something like Rhino Mock in conjunction with Ninject you can write and test your code (controllers, views, etc) without having to fully implement all of the functionality. When you're ready to implement a mocked piece of functionality, you don't have to rewrite your code to accommodate the changes, you simply update your bindings. Now real data will display on your pages instead of the mocked data you created previously.

MVC DDD: Is it OK to use repositories together with services in the controller?

most of the time in the service code I would have something like this:
public SomeService : ISomeService
{
ISomeRepository someRepository;
public Do(int id)
{
someRepository.Do(id);
}
}
so it's kinda redundant
so I started to use the repositories directly in the controller
is this ok ? is there some architecture that is doing like this ?
You lose the ability to have business logic in between.
I disagree with this one.
If business logic is where it should be - in domain model, then calling repo in controller (or better - use model binder for that) to get aggregate root and call method on it seems perfectly fine to me.
Application services should be used when there's too much technical details involved what would mess up controllers.
I've seen several people mention using model binders to call into a repo lately. Where is this crazy idea coming from?
I believe we are talking about 2 different things here. I suspect that Your 'model binder' means using model simultaneously as a view model too and binding changed values from UI directly right back to it (which is not a bad thing per se and in some cases I would go that road).
My 'model binder' is a class that implements 'IModelBinder', that takes repository in constructor (which is injected and therefore - can be extended if we need caching with some basic composition) and uses it before action is called to retrieve aggregate root and replace int id or Guid id or string slug or whatever action argument with real domain object. Combining that with input view model argument lets us to write less code. Something like this:
public ActionResult ChangeCustomerAddress
(Customer c, ChangeCustomerAddressInput inp){
c.ChangeCustomerAddress(inp.NewAddress);
return RedirectToAction("Details", new{inp.Id});
}
In my actual code it's a bit more complex cause it includes ModelState validation and some exception handling that might be thrown from inside of domain model (extracted into Controller extension method for reuse). But not much more. So far - longest controller action is ~10 lines long.
You can see working implementation (quite sophisticated and (for me) unnecessary complex) here.
Are you just doing CRUD apps with Linq To Sql or trying something with real domain logic?
As You can (hopefully) see, this kind of approach actually almost forces us to move towards task based app instead of CRUD based one.
By doing all data access in your service layer and using IOC you can gain lots of benefits of AOP like invisible caching, transaction management, and easy composition of components that I can't imagine you get with model binders.
...and having new abstraction layer that invites us to mix infrastructure with domain logic and lose isolation of domain model.
Please enlighten me.
I'm not sure if I did. I don't think that I'm enlightened myself. :)
Here is my current model binder base class. Here's one of controller actions from my current project. And here's "lack" of business logic.
If you use repositories in your controllers, you are going straight from the Data Layer to the Presentation Layer. You lose the ability to have business logic in between.
Now, if you say you will only use Services when you need business logic, and use Repositories everywhere else, your code becomes a nightmare. The Presentation Layer is now calling both the Business and Data Layer, and you don't have a nice separation of concerns.
I would always go this route: Repositories -> Services -> UI. As soon as you don't think you need a business layer, the requirements change, and you will have to rewrite EVERYTHING.
My own rough practices for DDD/MVC:
controllers are application-specific, hence they should only contain application-specific methods, and call Services methods.
all public Service methods are usually atomic transactions or queries
only Services instantiate & call Repositories
my Domain defines an IContextFactory and an IContext (massive leaky abstraction as IContext members are IDBSet)
each application has a sort-of Composition Root, which is mainly instantiating a Context Factory to pass to the Services (you could use DI container but not a big deal)
This forces me to keep my business code, and data-access out of my controllers. I find it a good discipline, given how loose I am when I don't follow the above!
Here is the thing.
"Business Logic" should reside in your entities and value objects.
Repositories deal with AggregateRoots only. So, using your repositories directly in your Controllers kinda feels like you are treating that action as your "service". Also, since your AggregateRoot may only refer to other ARs by its ID, you may have to call one more than one repo. It really gets nasty very quickly.
If you are going to have services, make sure you expose POCOs and not the actual AggregateRoot and its members.
Your repo shouldn't have to do any operations other than creating, retrieving, updating and deleting stuff. You may have some customized retrieve based on specific conditions, but that's about it. Therefore, having a method in your repo that matches one in your service... code smell right there.
Your service are API oriented. Think about this... if you were to pack that service in a .dll for me to use, how would you create your methods in a way that is easy for me to know what your service can do? Service.Update(object) doesn't make much sense.
And I haven't even talked about CQRS... where things get even more interesting.
Your Web Api is just a CLIENT of your Service. Your Service can be used by another service, right? So, think about it. You most likely will need a Service to encapsulate operations on AggregateRoots, usually by creating them, or retrieving them from a repo, do something about it, then returning a result. Usually.
Makes sense?
Even with "rich domain model" you will still need a domain service for handling business logic which involves several entities. I have also never seen CRUD without some business logic, but in simple sample code. I'd always like to go Martin's route to keep my code straightforward.

What is the correct layer to configure your IoC container when using a service layer?

I have a medium sized asp.net MVC app. It consumes a service layer that handles all the repository use, calling domain services, etc. My controller actions are very slim -- they basically call a service class, get a response and show that respose. Most components are interface based with some poor man's DI. The app is growing, needs better testing support, and starting to call out for an IoC container.
Everything I read (such as this SO question) states that I should configure the IoC at the application root. This makes sense to me if I were using repositories right from my controller actions and needed DI at the controller level, but I'm not. It seems like I'd want my composition root in my service layer. I keep thinking that I don't want my web.config (or another config) at the UI layer even mentioning/seeing/hearing about a repository, credit card processor, etc.
Am I thinking about this the right way or do I just need to get over it?
I have the same situation as you and I tackle it as follows.
The general rule I use is what ever has a global.asax or something similar, it needs to execute the code that registers the IoC components. Another way of putting it is that you need to run it one for each different process that is running (i.e. the website is in one process and the service is in another).
In my case I do this once for the mvc website global.asax and again for the server. In this case the registrations that get made would be different between the service and the website.
In addition I do one more thing. Due to the fact that I reuse components between the mvc app and the service (i.e. logging) I have a third core component that registers the core IoC components for the system and this component is called by the both the website and services registrations. Hence I anything that is common between the service and the website go into the core registration and then anything that is different goes into the 'interface' specific registration.
Hope that helps.
You just need to get over it :)
Having your Composition Root in the application root doesn't require you to have a lot of DI Container stuff in web.config. You can if you will, but it's optional. What is not optional when putting the Composition Root in the application root is that you need to have some DI code in Global.asax.
You may find it irrelevant because your Controllers are so thin, but that's not the real point. The actual point is that you (the abstract 'you') want to postpone coupling classes until the last responsible moment. The earlier you couple types, the less flexibility you have.
If you couple classes in the service layer, you make an irreversible decision at that point. If it later turns out that you need to compose those services differently, you can't - not without recompiling, that is.
If there was a major benefit of doing it, I can understand why you would want to, but there isn't. You may as well wait composing all components untill you absolutely must do so - and that's in the application's entry point.
Coming from a Java perspective, I use the Spring framework for my IoC container. With it, the container really is application-wide. Although you can have different configuration files for different layers (a persistence config file, a services config file, a controller config file, etc), all of objects (beans in Java lingo) go into the container.
I think this still ok though because there is no coupling between classes as you mentioned. A view does not need to know about a credit card processor, just because they are in the same IoC container. These classes will receive (by injection) only the dependencies they need, and are not concerned with other objects in the container.

Where to instantiate Data Context (adapter, connection, session, etc) in MVC?

We are building an ASP.NET MVC site, and I'm struggling with where to define a connection to best enable unit testing (I use 'connection' generically - it could be a session, a connection, an adapter, or any other type of data context that can manage transactions and database operations).
Let's say we have 3 classes:
UserController
UserService
UserRepository
In the past, we'd do something like this within a method of the UserService:
Using (ISomeSession session = new SomeSession())
{
session.StartTransaction();
IUserRepository rep = new UserRepository(session);
rep.DoSomething();
rep.Save();
session.Commit();
}
However, it wasn't really possible to unit test this since the dependency on SomeSession wasn't injected. However, if we use D.I. to inject the dependency in the UserService, the session hangs around for the life of the UserService. If there are multiple services called from the UserController, each could have sessions just hanging around until the UserController is garbage collected.
Any thoughts on how to better manage this? Am I missing something obvious?
Edit
Sorry if I wasn't clear - I understand that I can use Dependency Injection with the Session/Data Context, but then it's being maintained over the life of the Service class. For any longer-running actions/methods (i.e. let's say the service is being called by a batch process), this could lead to a lot of open sessions for no reason other than adding testability.
As RichardOD correctly observed, you can't use live database connections for writing unit tests. If you are doing it, then you are integration testing.
I have separate implementations for my repository interface, one real repository, and one fake repository for unit testing. The fake repository works on a generic list instead of a real data context. I am using DI (with Ninject to make things more comfortable, but you can do it just as well by hand) to inject the correct repository.
There are only very few instances in which I am unit testing with real connections, but that's a unit test for my repository class, not for any controller, UI or Business layer objects.
Edit: With the comment you added, I think I now understand what you were actually asking for. Funny you'd ask something about that, since I worked on the very same subject last week :-)
I instantiate the data context inside a very thin wrapper and put the context inside the HttpContext.Current.Items dictionary. This way, the context is global, but only for the current request.
Still, your question's subject is highly misleading. You were asking "where to instantiate a data context for unit testing" and the answer is that you usually don't. My unit tests still operate on fake repositories.
The easiest way is to have a Connectionstring that you define in web.config for development and production. For Unittests you define it in app.config of your Testproject.

Resources