I have a class something like this:
public class ABCHelper : ABCBase, IABCHelper
{
public ABCHelper()
: base(LogManager.GetCurrentClassLogger())
{
}
}
public class ABCBase : IABCBase
{
protected readonly Logger logger;
protected ABCBase(Logger logger)
{
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public async Task<HttpResponseMessage> MakeAsyncCall(HttpRequestMessage request)
{
// some code
this.logger.Info("some string");
}
}
Class registration in Unity:
container.RegisterType<IABCHelper, ABCHelper>();
When I call MakeAsyncCall in some code flow, NLog logs the classname as "DynamicBuildPlanGenerationContext".
I was expecting "ABCHelper" instead of "DynamicBuildPlanGenerationContext".
What am I missing?
First of all, it a bit debatable if ABCHelper is your current class, as it isn't constructed yet ;)
I think Unity is using some tricks for efficiently constructing the dependencies. The description of DynamicBuildPlanGenerationContext
This object tracks the current state of the build plan generation, accumulates the Microsoft intermediate language, provides the preamble & postamble for the dynamic method, and tracks things like local variables in the generated MSIL so that they can be reused across MSIL generation strategies.
NLog tries to find the current class name by checking the callstack, but can't find it probably due to optimizations.
I think case the easiest fix is by using named loggers, e.g. by using LogManager.GetLogger(string)
public class ABCHelper : ABCBase, IABCHelper
{
public ABCHelper()
: base(LogManager.GetLogger(nameof(ABCHelper)))
{
}
}
Side note, maybe it's because of the demo, but I don't see here the logger proper injected. If you don't want to use DI for loggers, you could just create a static field?
If you do like to use injected loggers, then I would recommend to checkout Microsoft.Extensions.Logging with NLog.Extensions.Logging which also works with Unity and .NET Framework. This could be also useful then: Resolve generic Microsoft.Extensions.Logging.ILogger<T> with Unity - get InvalidCastException
Or you could use
Related
When using LibLog, is it possible to assert calls to the logger? Given the wiki lists the following example for usage:
public class MyClass
{
private static readonly ILog Logger = LogProvider.For<MyClass>();
}
Here the logger is an implementation detail hidden from the consumer, which is most of the benefit of using this library. Such that the library consumer does not have to worry about how loggers are instantiated. Looking at this blog post:
http://dhickey.ie/2015/06/capturing-log-output-in-tests-with-xunit2/
It seems that a lot of boiler plate is added to capture the log output, I'm not entirely sure about the approach, given that it also uses a redirected Serilog output in the unit test, something that seems odd given the library should only rely on the logging abstraction?
The only options I can currently think of are:
Inject the logger - This probably would be odd for the consumer of the library, and each library then would carry it's own ILogger definition that needs to be injected, defeating the advantages of the abstraction.
Wire up to a real logging framework - Set the current LogProvider for LibLog to use Log4Net or similar, and then somehow try and inject a mock / stub Logger into Log4Net, and assert calls via proxy.
Any relatively simple way to assert calls to the logger would be appreciated, but I suspect parallel test execution would cause problems even if it was possible to assert calls on the above logger?
In the logging config for almost all loggers you can configure then to throw exception when log fail.
Sample from nlog
<nlog throwExceptions="true">
... your nlog config
</nlog>
But in the abstraction created by LibLog you lost this features
What I've done in my project:
I've created my LoggerFactory. It exposes same static methods as NLogger.
public class LoggerFactory
{
private static ILoggerFactoryStrategy _loggerFactoryStrategy = new DummyLoggerFactoryStrategy();
public static void Initialize(ILoggerFactoryStrategy loggerFactoryStrategy)
{
_loggerFactoryStrategy = loggerFactoryStrategy;
}
public ILogger GetLogger<T>()
{
return _loggerFactoryStrategy.GetLogger<T>();
}
....
}
Dummy strategy can write just to debug output or do nothing. Another strategy could look smth like:
public class LoggerFactoryStrategy : ILoggerFactoryStrategy
{
public ILogger GetLogger<T>()
{
//create LibLog instance instead with LogProvider.For<T>()
var nlogger = LogManager.GetLogger(typeof(T).Name); //create instance of NLogger
return new NLogLogger(nlogger);
}
}
And NlogLogger wrapper could be smth like
internal class NLogLogger : ILogger
{
private readonly Logger _logger;
public NLogLogger(Logger logger)
{
_logger = logger;
}
public void Debug(string message)
{
_logger.Debug(message);
}
public void Warn(string message, params object[] args)
{
_logger.Warn(message, args);
}
public void Info(Exception exception)
{
_logger.Info(exception);
}
......
}
When application starts I initialize it with proper strategy what uses NLogger under the hood.
If I want to test calls to logger I can use mocked strategy.
This approach lets you to remove references to logger library across your solution, except your root projects and lets you switch from one to another if you need in the future.
Also, this allowed us to use NLogger in PCL projects.
How can I inject different implementation of object for a specific class?
For example, in Unity, I can define two implementations of IRepository
container.RegisterType<IRepository, TestSuiteRepositor("TestSuiteRepository");
container.RegisterType<IRepository, BaseRepository>();
and call the needed implementation
public BaselineManager([Dependency("TestSuiteRepository")]IRepository repository)
As #Tseng pointed, there is no built-in solution for named binding. However using factory method may be helpful for your case. Example should be something like below:
Create a repository resolver:
public interface IRepositoryResolver
{
IRepository GetRepositoryByName(string name);
}
public class RepositoryResolver : IRepositoryResolver
{
private readonly IServiceProvider _serviceProvider;
public RepositoryResolver(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public IRepository GetRepositoryByName(string name)
{
if(name == "TestSuiteRepository")
return _serviceProvider.GetService<TestSuiteRepositor>();
//... other condition
else
return _serviceProvider.GetService<BaseRepositor>();
}
}
Register needed services in ConfigureServices.cs
services.AddSingleton<IRepositoryResolver, RepositoryResolver>();
services.AddTransient<TestSuiteRepository>();
services.AddTransient<BaseRepository>();
Finally use it in any class:
public class BaselineManager
{
private readonly IRepository _repository;
public BaselineManager(IRepositoryResolver repositoryResolver)
{
_repository = repositoryResolver.GetRepositoryByName("TestSuiteRepository");
}
}
In addition to #adem-caglin answer I'd like to post here some reusable code I've created for name-based registrations.
UPDATE Now it's available as nuget package.
In order to register your services you'll need to add following code to your Startup class:
services.AddTransient<ServiceA>();
services.AddTransient<ServiceB>();
services.AddTransient<ServiceC>();
services.AddByName<IService>()
.Add<ServiceA>("key1")
.Add<ServiceB>("key2")
.Add<ServiceC>("key3")
.Build();
Then you can use it via IServiceByNameFactory interface:
public AccountController(IServiceByNameFactory<IService> factory) {
_service = factory.GetByName("key2");
}
Or you can use factory registration to keep the client code clean (which I prefer)
_container.AddScoped<AccountController>(s => new AccountController(s.GetByName<IService>("key2")));
Full code of the extension is in github.
You can't with the built-in ASP.NET Core IoC container.
This is by design. The built-in container is intentionally kept simple and easily extensible, so you can plug third-party containers in if you need more features.
You have to use a third-party container to do this, like Autofac (see docs).
public BaselineManager([WithKey("TestSuiteRepository")]IRepository repository)
After having read the official documentation for dependency injection, I don't think you can do it in this way.
But the question I have is: do you need these two implementations at the same time? Because if you don't, you can create multiple environments through environment variables and have specific functionality in the Startup class based on the current environment, or even create multiple Startup{EnvironmentName} classes.
When an ASP.NET Core application starts, the Startup class is used to bootstrap the application, load its configuration settings, etc. (learn more about ASP.NET startup). However, if a class exists named Startup{EnvironmentName} (for example StartupDevelopment), and the ASPNETCORE_ENVIRONMENT environment variable matches that name, then that Startup class is used instead. Thus, you could configure Startup for development, but have a separate StartupProduction that would be used when the app is run in production. Or vice versa.
I also wrote an article about injecting dependencies from a JSON file so you don't have to recompile the entire application every time you want to switch between implementations. Basically, you keep a JSON array with services like this:
"services": [
{
"serviceType": "ITest",
"implementationType": "Test",
"lifetime": "Transient"
}
]
Then you can modify the desired implementation in this file and not have to recompile or change environment variables.
Hope this helps!
First up, this is probably still a bad idea. What you're trying to achieve is a separation between how the dependencies are used and how they are defined. But you want to work with the dependency injection framework, instead of against it. Avoiding the poor discover-ability of the service locator anti-pattern. Why not use generics in a similar way to ILogger<T> / IOptions<T>?
public BaselineManager(RepositoryMapping<BaselineManager> repository){
_repository = repository.Repository;
}
public class RepositoryMapping<T>{
private IServiceProvider _provider;
private Type _implementationType;
public RepositoryMapping(IServiceProvider provider, Type implementationType){
_provider = provider;
_implementationType = implementationType;
}
public IRepository Repository => (IRepository)_provider.GetService(_implementationType);
}
public static IServiceCollection MapRepository<T,R>(this IServiceCollection services) where R : IRepository =>
services.AddTransient(p => new RepositoryMapping<T>(p, typeof(R)));
services.AddScoped<BaselineManager>();
services.MapRepository<BaselineManager, BaseRepository>();
Since .net core 3, a validation error should be raised if you have failed to define a mapping.
(I originally asked this question in this comment, but Mark Seemann asked me to create a new question instead.)
I'm starting a new app (.NET Core, if that matters), and right now I'm trying to decide how exactly to do logging.
The general consensus seems to be that logging is a cross-cutting concern, so the logger shouldn't be injected directly into the class that is supposed to log.
Often, there's an example like the following class how not to do it:
public class BadExample : IExample
{
private readonly ILogger logger;
public BadExample(ILogger logger)
{
this.logger = logger;
}
public void DoStuff()
{
try
{
// do the important stuff here
}
catch (Exception e)
{
this.logger.Error(e.ToString());
}
}
}
Instead, the class with the business logic shouldn't know about the logger (SRP) and there should be a separate class which does the logging:
public class BetterExample : IExample
{
public void DoStuff()
{
// do the important stuff here
}
}
public class LoggingBetterExample : IExample
{
private readonly IExample betterExample;
private readonly ILogger logger;
public LoggingBetterExample(IExample betterExample, ILogger logger)
{
this.betterExample = betterExample;
this.logger = logger;
}
public void DoStuff()
{
try
{
this.betterExample.DoStuff();
}
catch (Exception e)
{
this.logger.Error(e.ToString());
}
}
}
Whenever an IExample is needed, the DI container returns an instance of LoggingBetterExample, which uses BetterExample (which contains the actual business logic) under the hood.
Some sources for this approach:
Blog posts by Mark Seemann:
Instrumentation with Decorators and Interceptors
Dependency Injection is Loose Coupling
Blog post and SO answer by Steven:
Meanwhile... on the command side of my architecture
Windsor - pulling Transient objects from the container
My question:
Obviously, the LoggingBetterExample approach only works as long as the logging can be done outside the actual class.
(like in the example above: catch any exceptions thrown by BetterExample from outside)
My problem is that I'd like to log other things inside the actual class.
Mark Seemann suspected here that if someone needs to do this, maybe the method in question is doing too much.
As I said before, I'm in the planning phase for a new application, so I don't have much code to show, but the use case I'm thinking right now is something like this:
My app will have a config file with some optional values.
The user may decide to omit the optional values, but it's an important decision to do this.
So I'd like to log a warning when some of the optional values are missing, just in case it happened by error.
(omitting the values is perfectly fine though, so I can't just throw an exception and stop)
This means that I will have a class which reads config values and needs to do something like this (pseudocode):
var config = ReadConfigValues("path/to/config.file");
if (config.OptionalValue == null)
{
logger.Warn("Optional value not set!");
}
No matter if ReadConfigValues is in this class or a different one, I don't think this class would violate the SRP.
When I'm not able to log outside the actual class by using a decorator, is there a better solution than to inject the logger?
I know I could read the config file in the inner class, but check the values (and log the warning) in the decorator. But IMO checking the value is business logic and not infrastructure, so to me it belongs in the same class where the config file is read.
checking the value is business logic and not intfastructure, so to me it belongs in the same class where the config file is read.
Obviously, I don't know your domain well enough to dispute the truth of that assertion, but that logging is part of the domain model sounds strange to me. Anyway, for the sake of argument, let's assume that this is the case.
What ought not to be the case, though, is that reading a configuration file is domain logic. While reading and manipulating the data from a file could easily be domain logic, reading a file is I/O.
The most common approach to Inversion of Control in application architecture is to employ the Ports & Adapters architecture. The entire point of such an architecture is to decouple the domain model from I/O, and other sources of non-determinism. The poster example is to show how to decouple the domain model from its database access, but file access falls squarely in that category as well.
What this ought to imply in this particular case is that you're going to need some IConfigurationReader interface anyway. This means that you can apply a Decorator:
public class ValidatingConfigurationReader : IConfigurationReader
{
private readonly IConfigurationReader reader;
private readonly ILogger logger;
public ValidatingConfigurationReader(IConfigurationReader reader, ILogger logger)
{
this.reader = reader;
this.logger = logger;
}
public MyConfiguration ReadConfigValues(string filePath)
{
var config = this.reader.ReadConfigValues(filePath);
if (config.OptionalValue == null)
{
this.logger.Warn("Optional value not set!");
}
return config;
}
}
This ValidatingConfigurationReader class can be implemented in the domain model, even if the underlying, file-reading IConfigurationReader implementation belongs in some I/O layer.
Don't take SRP so seriously, otherwise you'll end up with functional programming. If you afraid of getting your class cluttered by putting log statements inside it, then you have two options. The first one you already mentioned which is using a Decorator class but you can't access/log the private stuff. The second option is using partial classes and putting the logging statements in a separate class.
I am working on an app which uses active directory to retrieve users. Sometimes I need to work on the app but AD is not available. I use a wrapper class to retrieve the AD user. I would like to inject a different class based on the configuration. I was thinking on using an appSetting that would tell me the current configutarion and decide what type to use when injecting. Is it possible to get the current configuration without using a Web.config transform? Is it possible to inject objects using Unity based on Web.config transformations? Can you recommend a better approach?
[UPDATE]
I have a user repository class that loads the users from AD. All I need is to be able to change the implementation of this repository class so that when AD is unavailable I can load the users a different way. This would only be used for development, production would always access AD and retrieve users.
You can use preprocessor directives:
#if DEBUG
// register fake repository
#else
// register AD repository
#endif
Well, Dependency Injection is incredibly powerful, agile, and creates a separation of concerns. The pitfall in your approach will come from validation. You see, with this approach you have to choose a concrete implementation.
So how will you call those two classes?
public class LogToText : ILogger
{
public void LogMessage(string message) { }
}
public class LogToEvent : ILogger
{
public void LogMessage(string message) { }
}
You have these two implementations, but when you pass the interface to:
public class AD
{
public AD(ILogger logger) { }
}
So the question will be do you feel that you can properly validate to choose the proper implementation effectively. Otherwise, Dependency Injection may not work well. We don't entirely know the usage or goal, so our advice may not be truly beneficial. Hopefully you see what I mean, because you'll have to see if you can't test a particular way.
You could use an Abstraction for this:
public interface IPersonService
{
IEnumerable<Person> Find(PersonSearchParameters searchParams);
Person GetByAccountName(string accountName);
[ETC...]
}
Then both your AD and Development implements this interface.
To make things easier, I suggest using StructureMap IoC, so you can easily do this:
x.For<IPersonService>.Use<ActiveDirectoryPersonService>(); //for production
or
x.For<IPersonService>.Use<MockPersonService>(); //for development
When using this you can, for instancce:
public class TestController : Controller
{
IPersonService _service;
public TestController(IPersonService service)
{
_service = service;
}
}
Instead of using an XML file for configuration in this case, I suggest using the Fluent code of Structure Map, it's better when refactoring and to avoid mistyping because it compiles.
StructureMap:
http://structuremap.net
Easy Installable via NuGET
A different approach would be to use the build configuration, read back from the assembly.
var buildConfiguration = typeof(Program).Assembly.GetCustomAttribute<AssemblyConfigurationAttribute>()?.Configuration;
if (buildConfiguration == "Debug")
{
// register fake repository
}
else
{
// register AD repository
}
Then it is safer to apply refactorings or automatic code clean up (e.g. ReSharper etc.). Depending on your current configuration, code cleanup can otherwise remove unused usings. What then leads to build issues if an other configuration is used.
I was asked to implement castle dynamic proxy in my asp.net web application and i was going through couple of articles which i got from Castle Project and Code Project about castle dynamic proxy in asp.net web application....
Both articles delt with creating interceptors but i can't get the idea why interceptors are used with classes.... Why should i intercept my class which is behaving properly?
Let's say that your class needs to do 3 things for a certain operation:
Perform a security check;
Log the method call;
Cache the result.
Let's further assume that your class doesn't know anything about the specific way you've configured your security, logging, or caching. You need to depend on abstractions of these things.
There are a few ways to go about it. One way would be to set up a bunch of interfaces and use constructor injection:
public class OrderService : IOrderService
{
private readonly IAuthorizationService auth;
private readonly ILogger logger;
private readonly ICache cache;
public OrderService(IAuthorizationService auth, ILogger logger,
ICache cache)
{
if (auth == null)
throw new ArgumentNullException("auth");
if (logger == null)
throw new ArgumentNullException("logger");
if (cache == null)
throw new ArgumentNullException("cache");
this.auth = auth;
this.logger = logger;
this.cache = cache;
}
public Order GetOrder(int orderID)
{
auth.AssertPermission("GetOrder");
logger.LogInfo("GetOrder:{0}", orderID);
string cacheKey = string.Format("GetOrder-{0}", orderID);
if (cache.Contains(cacheKey))
return (Order)cache[cacheKey];
Order order = LookupOrderInDatabase(orderID);
cache[cacheKey] = order;
return order;
}
}
This isn't horrible code, but think of the problems we're introducing:
The OrderService class can't function without all three dependencies. If we want to make it so it can, we need to start peppering the code with null checks everywhere.
We're writing a ton of extra code to perform a relatively simple operation (looking up an order).
All this boilerplate code has to be repeated in every method, making for a very large, ugly, bug-prone implementation.
Here's a class which is much easier to maintain:
public class OrderService : IOrderService
{
[Authorize]
[Log]
[Cache("GetOrder-{0}")]
public virtual Order GetOrder(int orderID)
{
return LookupOrderInDatabase(orderID);
}
}
In Aspect Oriented Programming, these attributes are called Join Points, the complete set of which is called a Point Cut.
Instead of actually writing dependency code, over and over again, we leave "hints" that some additional operations are supposed to be performed for this method.
Of course, these attributes have to get turned into code sometime, but you can defer that all the way up to your main application code, by creating a proxy for the OrderService (note that the GetOrder method has been made virtual because it needs to be overridden for the service), and intercepting the GetOrder method.
Writing the interceptor might be as simple as this:
public class LoggingInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
if (Attribute.IsDefined(invocation.Method, typeof(LogAttribute))
{
Console.Writeline("Method called: "+ invocation.Method.Name);
}
invocation.Proceed();
}
}
And creating the proxy would be:
var generator = new ProxyGenerator();
var orderService = (IOrderService)generator.CreateClassProxy(typeof(OrderService),
new LoggingInterceptor());
This is not only a lot less repetitive code, but it completely removes the actual dependency, because look what we've done - we don't even have an authorization or caching system yet, but the system still runs. We can just insert the authorization and caching logic later by registering another interceptor and checking for AuthorizeAttribute or CacheAttribute.
Hopefully this explains the "why."
Sidebar: As Krzysztof Koźmic comments, it's not a DP "best practice" to use a dynamic interceptor like this. In production code, you don't want to have the interceptor running for unnecessary methods, so use an IInterceptorSelector instead.
The reason you would use Castle-DynamicProxy is for what's called Aspect Orientated Programming. It lets you interject code into the standard operation flow of your code without the need to become dependent on the code itself.
A simple example is as always, logging. That you would create a DynamicProxy around a class that you have errors from that it logs the data going into the method and catches any exceptions and then logs the exception.
Using the intercepter your current code has no idea it exists (assuming you have your software built in a decoupled way with interfaces correctly) and you can change the registration of your classes with an inversion of control container to use the proxied class instead without having to change a single line else where in code. Then when you solve the bug you can turn off the proxying.
More advanced usage of proxying can be seen with NHibernate where all of the lazy loading is handled through proxies.