I have an interface
public interface ILoggerService
{
void Info(string message);
void Warn(string message);
}
Then, i have a class which implements this interface and logs using Log4Net
public class Log4NetLoggerService : ILoggerService
{
private readonly ILog _logger;
public Log4NetLoggerService()
{
// this always returns Log4NetLoggerService class type
_logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
}
public void Info(string message)
{
_logger.Info(message);
}
}
This works fine, but the problem is that if i want to log the current class and method name, (using %class - %M), this always returns Log4NetLoggerService as the class, and as the method it returns Info as the method.
I need to get the "parent" class type, which called the logging method.
Can i inject somehow the type of the class which calls the log methods when i create the ILoggerService instance?
Have a look at the log4net source code; specifically how they implemented the ILog interface. You basically cannot use the ILog interface in your wrapper, instead you use the internal logger which accepts a parameter that instructs log4net where to look for the correct class / method in the call stack. See also this answer.
In my experience, if you need the name of the class you're logging in, you're probably logging too much and from too many places in your application. This can lead to maintenance problems. Take a look at this Stackoverflow answer to verify if you're not logging too much and if you're not violating the SOLID principles.
Related
I am experiencing an issue, and I have come to a dead end on how to debug and resolve this.
I have an MVC application which is using Ninject for IoC and DI.
One of my dependencies is IApplicationLogger which I am currently implementing using Log4Net.
In my NinjectWebCommon I am binding my IApplicationLogger as follows:
kernel.Bind<IApplicationLogger>()
.ToMethod(ctx =>
{
string configFile = System.Configuration.ConfigurationManager.AppSettings["log4netconfigfilelocation"];
log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo(HttpContext.Current.Server.MapPath(configFile)));
var name = ctx.Request.Target.Member.DeclaringType.FullName;
var log4Netlogger = log4net.LogManager.GetLogger(name);
return new Log4NetApplicationLogger(log4Netlogger);
}).InTransientScope();
All fairly straight forward stuff.
However, I am finding that the first instance of IApplicationLogger which is activated is then passed to all constructors which require an IApplicationLogger instance.
for example I have the following
public class A : IA
{
public A(IB bclass, IC cclass, IApplicationLogger logger){}
}
public class B : IB
{
public B(IApplicationLogger logger){}
}
public class C : IC
{
public C(IApplicationLogger logger){}
}
I have set breakpoints on each constructor and also the line in my NinjectWebCommon kernel.Bind().ToMethod(ctx =>
What I see is this:
Break point in NinjectWebCommon is hit, and I can see
ctx.Request.Target.Member.DeclaringType.FullName is Class B.
Break point in Constructor Class B is hit and logger
instance is correct
Break point in Constructor Class C is hit, and
logger instance has a logger name of Type Class B
Break point in Constructor Class A is hit, and logger instance has a logger
name of Class B
I would expect the breakpoint within NinjectWebCommon to be hit for each new instance of IApplicationLogger that is required, but it is only hit once for the first activation for the instance of Class B.
I have tried my Binding without the InTransientScope() option.
My IA, IB and IC bindings are defined InSingletonScope(). This shouldn't cause an issue as I am expecting Ninject to activate an instance of each, each with it's own instance of IApplicationLogger.
The result of the binding I am seeing currently is that logging statements I output in say Class A are being recorded in the Log as being from a logger name for class of type B.
Can anyone suggest how I can diagnose why Ninject is reusing the TransientScoped() IApplicationLogger, or how I can peek under the hood of what Ninject is doing so that I can analyse this in greater detail?
For anyone interested I didn't discover the underlying issue here, but I have opted to inject an ILoggerFactory with a single method .GetLogger(string typename), allowing my classes to request their own Logger and passing their own Type name.
This way I can ensure that each Class has it's own logger, with the LoggerName matching the Class TypeName.
So, is it not recommended using an inheritance-approach when implementing Grails services? I went through a simple service specialization pattern understanding that all would work in a transparent way, but I started to go into trouble regarding transaction management under the spring/grails hood. Issues happen when a method from the specialized class calls a method from the inherited class (both concrete services themselves):
#Transactional
public class MammalService {
public mammalMethod() {
}
}
#Transactional
public class DogService extends MammalService {
public dogMethod() {
mammmalMethod()
}
}
It comes that when the inherited method is called from the specialized one, org.springframework.transaction.support.GrailsTransactionTemplate() constructor is fired (by the spring/grails transaction AOP) with a null transactionManager argument, which causes some NullPointerException moreover.
Has anyone used such approach with services? Am I missing something?
PS: Curiously, I tried changing the #grails.transaction.Transactional annotation by the #org.springframework.transaction.annotation.Transactional and the NullPointerException ceased from happening. (Nevertheless, it didn't point to a nice solution, since other side effects started to happen with my pool management).
UPDATE1: While debugging, I can see TWO variables with the same name transactionManager inside my specialized service (something that doesn't happen when inspecting the concrete superclass).
I'm opening a more specific issue at Duplicated transactionManager property in Grails service
Solved by removing #Transaction from specialized service classes and
methods, keeping them only on the inherited service class and its methods.
#Transactional
public class MammalService {
#Transactional(readonly=true)
public mammalMethod() {
}
}
//Don't annotate with #Transactional - rely on the super class declaration
public class DogService extends MammalService {
//Don't annotate with #Transactional - rely on the super class transactional declaration
public dogMethod() {
mammmalMethod()
}
}
It seems that, for specialized service classes, the transaction routines try to re-inject the transactionManager attribute, resulting in two attributes with the same name and one of them null. Also, annotating overrided methods raises an StackOverflowException.
I am writing an SDK and wanted to know how to write things more cleanly.
For example, I have a GodManager delegate class (which will be the central class that a user can interact with) (this is pseudocode-ish):
public class GodManager {
private CloudApi cloudApi;
private SensorApi sensorApi;
private CacheApi cacheApi;
.
. And about 5 more API classes of similar sorts
.
GodManager() {
cloudApi = new CloudApi();
sensorApi = new SensorApi()
cacheApi = new CacheApi();
}
public void someCloudApiMethodAccess() {
cloudApi.someCloudApiMethodAccess();
}
.
.
. And I have about 25 other methods where GodManager delegates to API classes
.
}
How do I allow access for my users via GodManager, but remove these 25 methods that are just proxy methods for each Api class?
I know that Android Wear does something with:
public class Wearable {
public static final com.google.android.gms.wearable.DataApi DataApi;
public static final com.google.android.gms.wearable.MessageApi MessageApi;
public static final com.google.android.gms.wearable.NodeApi NodeApi;
}
Where you can access these APIs in your code:
Wearable.DataApi.getFdForAsset(...)
So I'm guessing that I can mimic this and do something like:
class GodManager {
public static CloudApi CloudApi;
GodManager {
CloudApi = new CloudApi();
}
}
Then in my implementation classes, I can:
class ImplClass {
public void method() {
GodManager.CloudApi.someCloudApiMethodAccess()
}
}
Am I missing anything? Will there be some awkward side-effects that I haven't considered? Any advice would be greatly appreciated in an effort to clean up my GodManager.
Or maybe someone has some other examples that I can look at and learn from?
Creating public fields is usually an antipattern, although there are some legid uses. The danger lies in the fact that if a user has access to your field, it can do ANYTHING with it.
If CloudApi contains public methods or public fields of it's own, that the user should NOT mess with, then te ONLY solution is to make a huge delegate class. If you have full control over CloudApi, and/or you can ensure that it's only public members are those that may be safely, and unconditionally, accessed by others, then you can make the instance public. (which is the legid use)
(Note that making a member private and making a public getter for that method that returns the instance, is exactly the same!)
Even then, you're limiting yourself because you're defining your API (of GodManager) and you're preventing yourself from EVER extending functionality of the referenced instances. For example, you might want to make calls to CloudApi synchronized, or check parameter validity, but don't want (or can) change CloudApi. If you have delegate methods, you can extend the functionality without changing your GodManager API, and existing users don't break.
I frequently use AutoMapper to map Model (Domain) objects to ViewModel objects, which are then consumed by my Views, in a Model/View/View-Model pattern.
This involves many 'Mapper.CreateMap' statements, which all must be executed, but must only be executed once in the lifecycle of the application.
Technically, then, I should keep them all in a static method somewhere, which gets called from my Application_Start() method (this is an ASP.NET MVC application).
However, it seems wrong to group a lot of different mapping concerns together in one central location.
Especially when mapping code gets complex and involves formatting and other logic.
Is there a better way to organize the mapping code so that it's kept close to the ViewModel that it concerns?
(I came up with one idea - having a 'CreateMappings' method on each ViewModel, and in the BaseViewModel, calling this method on instantiation. However, since the method should only be called once in the application lifecycle, it needs some additional logic to cache a list of ViewModel types for which the CreateMappings method has been called, and then only call it when necessary, for ViewModels that aren't in that list.)
If you really don't want to use a bootstrapper, then at least a static constructor is an easy way of ensuring your CreateMap is called at most once. (With less messing around and more thread proof than Jonathon's answer.)
public class AccountController : Controller
{
static AccountController()
{
Mapper.CreateMap<Models.User, ViewModels.UserProfile>();
Mapper.CreateMap<Models.User, ViewModels.ChangePassword>();
}
}
If you use profiles, you can place all of your "CreateMap" calls there. Additionally, you can create a static bootstrapper class that contains your configuration, and have the startup piece just call the bootstrapper.
OK, the way I'm currently doing it is this:
I add some logic to the constructor of my BaseController, which runs the 'CreateMappings' method, but only once per Controller Type:
public abstract class BaseController : Controller
{
public BaseController()
{
if (!controllersWithMappingsCreated.Contains(GetType()))
{
CreateMappings();
controllersWithMappingsCreated.Enqueue(GetType());
}
}
protected virtual void CreateMappings() { }
}
In each concrete controller, I use CreateMappings to declare the mappings for all the Models/ViewModels relevant to that controller.
public class AccountController : BaseController
{
public AccountController() : base() { }
protected override void CreateMappings()
{
Mapper.CreateMap<Models.User, ViewModels.UserProfile>();
Mapper.CreateMap<Models.User, ViewModels.ChangePassword>();
}
}
I also found some interesting alternatives involving Attributes here and here, however they strike me as a bit overcomplicated.
If you don't know what I'm talking about either go through the tutorial and try to add dependency Injection yourself or try your luck with my explanation of the problem.
Note: This problem isn't within the scope of the original tutorial on ASP.NET. The tutorial only suggests that the patterns used are dependency injection friendly.
The problem is basically that there is a dependency loop between the Controller, the ModelStateWrapper and the ContactManagerService.
The ContactController constuctor takes an IContactManagerService.
The ContactManagerService constructor takes an IContactManagerRepository (not important) and an IValidationDictionary (which ModelStateWrapper implements).
The ModelStateWrapper constructor takes a ModelStateDictionary (which is a property called "ModelState" on the controller).
So the dependency cycle goes like this: Controller > Service > ModelStateWrapper > Controller
If you try to add dependency injection to this, it will fail. So my question is; what should I do about it? Others have posted this question, but the answers are few, different, and all seem kinda "hack-ish".
My current solution is to remove the IModelStateWrapper from the IService constructor and add an Initialize method instead like this:
public class ContactController : Controller
{
private readonly IContactService _contactService;
public ContactController(IContactService contactService)
{
_contactService = contactService;
contactService.Initialize(new ModelStateWrapper(ModelState));
}
//Class implementation...
}
public class ContactService : IContactService
{
private IValidationDictionary _validationDictionary;
private readonly IContactRepository _contactRepository;
public ContactService(IContactRepository contactRepository)
{
_contactRepository = contactRepository;
}
private void Initialize(IValidationDictionary validationDictionary)
{
if(validationDictionary == null)
throw new ArgumentNullException("validationDictionary");
_validationDictionary = validationDictionary;
}
//Class implementation...
}
public class ModelStateWrapper : IValidationDictionary
{
private readonly ModelStateDictionary _modelState;
public ModelStateWrapper(ModelStateDictionary modelState)
{
_modelState = modelState;
}
//Class implementation...
}
With this construct I can configure my unity container like this:
public static void ConfigureUnityContainer()
{
IUnityContainer container = new UnityContainer();
// Registrations
container.RegisterTypeInHttpRequestLifetime<IContactRepository, EntityContactRepository>();
container.RegisterTypeInHttpRequestLifetime<IContactService, ContactService>();
ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory(container));
}
Unfortunately this means that the "Initialize" method on the service has to be called manually by the controller constructor. Is there a better way? Maybe where I somehow include the IValidationDictionary in my unity configuration? Should I switch to another DI container? Am I missing something?
As a general consideration, circular dependencies indicate a design flaw - I think I can safely say this since you are not the original author of the code :)
I wouldn't consider an Initialize method a good solution. Unless you are dealing with an add-in scenario (which you aren't), Method Injection is not the right solution. You have almost already figured that out, since you find it unsatisfactory that you need to manually invoke it because your DI Container can't.
Unless I am entirely mistaken, the ContactController doesn't need the IValidationDictionary instance before its Action methods are being invoked?
If this is true, the easiest solution would probably be to define an IValidationDictionaryFactory interface and make the ContactController constructor take an instance of this interface.
This interface could be defined like this:
public interface IValidationDictionaryFactory
{
IValidationDictionary Create(Controller controller);
}
Any Action method on the controller that needs an IValidationDictionary instance can then invoke the Create method to get the instance.
The default implementation would look something like this:
public class DefaultValidationDictionaryFactory : IValidationDictionaryFactory
{
public IValidationDictionary Create(Controller controller)
{
return controller.ModelState;
}
}
How about slightly changing/improving the design to something like this: http://forums.asp.net/t/1486130.aspx
Each controller has a virtual method Initialize to do stuff like that.
I think there is no better way because the IValidationDictionary is an abstraction layer between you current request/controller/modelstate and the IContactService. Injecting controllers modelstate into the service and then injecting the service into the controller is simply impossible using constructor injection. One has to be first.
May be there is a way using property injection? But I think this will be complicated too.