I am working on a greenfield project and I want to integrate serilog with ninject.
The use case is as follows:
There are a number of common libraries
These libraries are used in a number of modules i.e plugins. These plugins each receive a GUID at run time which is unique. This
is a base property on an abstract plugin class which every
implementation of a plugin inherits
We want to append this unique name to every log message that a plugin makes
as well as any calls to the common libraries from that plugin so that a log
message can be traced to the unique instance of a plugin that made it
We would prefer not to modify each class in the common libraries to take in a logger to use to log
My thoughts were to :
Create a singleton logger provider. This will be called by anything needing to log.
Use postsharp and CallContext.LogicalSetData to set the GUID prior to any call to the logging provider
Use CallContext.LogicalGetData to get the GUID in the singleton logger provider. This will either retrieve an existing logger for that GUID using Logger.ContextFor or create a new one to add to a dictionary.
Use Ninject to resolve the ILoggerProvider to the singleton provider always when requested
Before I down this circuitious route, is there a better way to do this, maybe with ninject?
Thanks for reading.
I went with the solution as described but due to it being a singleton there was no need for ninject in the end.
The solution is working and doesnt seem to have any performance issues logging at high volumes
Related
Is it possible to use the Grails Cache plugin's annotations (ie: #Cacheable) on methods in normal Groovy classes? The plugin's documentation doesn't mention anything about normal Groovy classes and based on my own tests the annotations have no effect when used in a normal class. So I'm just wondering if there's a way to get the annotations to work in a normal Groovy class.
The current alternative is to simply directly access the cache in the method via the Cache Manager bean, but it would be nice to use the annotations instead.
No, the annotation only works on services and controllers. The plugin detects the annotation and creates a proxy for the service which intercepts all method calls and does the cache-related work first. So if there is a value in the cache for that method, it won't bother calling your real method but return the cached value instead. But if it's not cached, it will call your method and use its return value, but cache that for later.
This works because you have to retrieve the service from the Spring ApplicationContext (or have Grails do that for you) and this gives Spring a chance to give you the proxy instead of the real implementation instance, but there's no way for Spring to know about access to regular Groovy classes without AOP or some other more invasive solution.
Having said that, the plugin is probably being overly strict in limiting to only controllers and services. It handles controllers specially because those involve caching web requests instead of method return values, but there shouldn't be much difference between a Grails service and any other annotated Spring bean as far as caching goes. You can add your own Spring beans, either manually in grails-app/conf/spring/resources.groovy or by adding them to the grails.spring.bean.packages list in Config.groovy, so the plugin should be updated to look for all annotated classes. You can request this in the plugin's JIRA at https://jira.grails.org/browse/GPCACHE
What actually happens when we do def someService? Does the service code get linked to the controller code?
Grails uses spring IOC, your controllers and services are managed as spring beans, when you define a service inside a controller, spring will inject the service inside the controller, code does not get linked in anyway, just reference to service will be set. Though its not a much expensive operation, you would not want to define service dependencies that are not used to keep the code clean
I think under the hood it's the same process as Spring's #Autowired annotation, so you pay a bit of a performance penalty on start up but I don't think it's significant.
There's another stackoverflow question on the subject here.
Does the service code get linked to the controller code?
That does not make sense.
Actually services in grails are singleton by default.So if you inject a Service by def serviceName it wont create a new service object but a reference to same old service object.
So its not expensive of course.
But if in a service there is a property static session="prototype" or some non-singleton like this.Then it is expensive .
What is the best way to configure a Grails service with environment specific values? I believe there are two options:
access grailsApplication values from within the service class or
configure the service bean in a beans closure in Config.groovy or resources.groovy.
I've seen a couple of posts on stackoverflow and other places that show how to do #1 (accessing grailsApplication in the service). One such post is: Inject grails application configuration into service.
However, I think this creates an unnecessary coupling of the service to Grails. Isn't this similar to accessing Spring's applicationContext in a pojo rather than configuring/injecting the values? Also, I've not had any luck getting this to work in a unit test of the service class as of yet.
Two books have examples of injecting the properties (approach #2). The book The Definitive Guide to Grails 2, chapter 10, section entitled "Services in Action" shows how to do this, but without an environment specific value. The book Groovy and Grails Recipes, section 16-2 also shows an example using resources.groovy, but I've not been able to get it to work either yet.
The following blog post also has a nice example, but not environment specific: http://ldaley.com/post/1253952347/getting-more-out-of-property-override-configuration. Chapter 15 of the Grails Reference is consistent with these examples as well and shows how to set the properties on a bean on a per environment basis.
However, none of the examples of either approach give any opinion or rational for doing it one way or another. Is there really no pros and cons to either approach? Wouldn't the injection approach be easier to unit test and more consistent with the spring way of doing things?
Nathan
I'd say use whichever you're more comfortable with. I tend to go with accessing grailsApplication.config directly from the service, because that lets you make the configuration more "semantic" (for want of a better word) in the sense that you can name the configuration options after what they do, rather than which bean they control. And if two (or more) different beans need to know the site administrator's email address (for example) then they can both read grailsApplication.config.myapp.admin.email rather than my having to configure beans.monitorService.destinationEmail and beans.userService.fromEmail separately.
In unit tests you'd have to mock the grailsApplication config anyway, so it's no big deal filling in test values for the config options your services need to read.
There's a difference in the concept of services (classes that exists in the service folder) and Spring Beans defined in resources.groovy.
To services, Grails already setup transactions:
Services are typically involved with coordinating logic between domain
classes, and hence often involved with persistence that spans large
operations. Given the nature of services, they frequently require
transactional behaviour. You can use programmatic transactions with
the withTransaction method, however this is repetitive and doesn't
fully leverage the power of Spring's underlying transaction
abstraction.
The Spring Beans that you declared aren't transactional by default.
"However, I think this creates an unnecessary coupling of the service
to Grails"
Since Grails services differ from Spring Beans I don't see a problem using approach #1.
For Unit Tests you need to manually wire up you service instance. Example:
class MyService {
def grailsApplication
}
class MyServiceTests {
MyService getServiceInstance() {
MyService myService = new MyService()
myService.grailsApplication = grailsApplication //static attribute in unit tests
return myService
}
}
Imagine two Grails applications which share a domain class. Maybe a Book domain class.
One application is identified as the owner of the data, one will have to access the domain data. Something like amazon and the amazon web services.
I guess it is trivial that the owning application will use a normal domain class and will expose the data through web services - no problem in grails.
But what would be best practice to implement the domain in the other application?
use a service to access the remote domain and not implement a local domain class at all?
implement a local domain class, overwrite the get()-method in order to fetch the remote data and use the local database as cache?
what other solution comes to your mind?
Ryan Geyer has a very interesting article Modularizing your Grails application domain classes which lists 3 solutions to this problem:
As a RESTful JSON Service - easy to get this setup in Grails but then you lose the automatic GORM functionality.
Separate out the domain classes into a library JAR file and reference that library in both of my other applications. This is not as easy as it first sounds
Create a Grails plugin. Put the domain object in the plugin. Each of your applications can then import this plugin. You can then create different controllers with different functionality as required. The sample code for this is available at:
git clone git://ec2.nslms.com/grails/blog_example_modular
Ted Naleid gives a great tip later in the post and recommends...
"create a grails-app/conf/BuildConfig.groovy file and put the plugin name and path to the source in it. ... If you do this, your applications will see the live changes to your domain/controller/service/etc classes as if they were actually in current app and there isn't any need to repackage and reinstall the plugin when you make changes."
Using memcache should enable both applications to have a consistent view of the data and would avoid each individual application having it's own inconsistent cache.
I think you can make JAR file of your domain classes and add reference to other grails application .
Found another interesting solution:
Riak is a key/value database with a first class REST API. There is a grails plugin for riak which maps most of the GORM functionality (relations, dynamic finders etc) to the REST API of riak: http://grails.org/plugin/riak
Now comes the part which I haven't tested yet: if you make use of the DataSources feature of grails 2.0, it should be possible to only connect those "remote" domains to a riak database.
As a result, there would be a domain stored in a riak database and several applications would be able to access it via a clean REST API without effort.
OK. This also show how silly my question is - it would be the same if you connect several apps through the same SQL-database. But sometimes people want to have something more funky like webservices.
I'm using Autofac to implement IoC in my solution, But I am doubtful whether I'm doing it right or not. Here's the scenario:
I have some Manager classes which all derive from BaseManager class. The BaseManager has a protected User CurrentUser field. What I'm trying to do, is to resolve the CurrentUser using Autofac. I have written anIUserProvider interface and implemented a couple of classes (e.g. WebUserProvider and WinformsUserProvider).
Then I registered my provider as below (for example, in Global.asax):
builder.Register(c => new WebUserProvider(...)).As<IUserProvider>();
How can I resolve dependencies (access container in my classes)? I could use a singleton or a service locator pattern but seems like it's an anti-pattern. So how should I resolve my dependency?
This sounds like overengineering to me. Why would you have a base manager class that has knowledge of the user? Having a few manager classes is a code smell and a maintenance hazard on its own, as your are abstracting too much. Do you really need that?
How can I resolve dependencies (access container in my classes)?
You should not be looking for a way to access your container. Container must be initialized once, in a single place. You should inject all the dependencies via constructor. These dependencies are passed in from the root of the dependency graph using container.Resolve<T> and elsewhere in the dependency graph using constructor injection (or some folks use property injection).