Ninject.Extensions.Logging.nlog2 - How to? - asp.net-mvc

Browsing the nuget library, i came across Ninject.Extensions.Logging.nlog2. Some googling and trying to figure things out, I can't seem to find how or why you would use this extension.
Is it advisable to use with MVC 3?
What exactly is the point?
How do you use it?

It's really very simple; both NLog and log4net expect you to use singleton/static references to obtain logger instances:
private static Logger logger = LogManager.GetCurrentClassLogger();
This is widely considered to be an anti-pattern, but even if you have no problem with it, it's still going against the grain if you're trying to implement dependency injection. In the case of NLog it's not even an ILog or ILogger interface like log4net, it's an actual class. That carries certain disadvantages such as the inability to create proxies, deferred loading, caching, etc.
What the Ninject.Extensions.Logging project does is first provide an abstract ILogger class with simple methods like Info, Error, etc., so you can inject it as a dependency and switch the logging framework if you want:
public class WidgetProvider
{
private readonly ILogger log;
public WidgetProvider(ILogger log)
{
this.log = log;
}
}
This is how DI is supposed to work - a class never goes out to grab its own dependencies, instead they're supplied by the constructor or caller as above. Assuming you've already integrated Ninject itself into your project, that's really all you have to do, there is no additional work.
As for what Ninject.Extensions.Logging.NLog2 does specifically - it just provides an implementation for Ninject.Extensions.Logging based on NLog2. The base Logging library doesn't actually contain any implementations of ILogger, you have to plug in one of the specific libraries (NLog, NLog2, or log4net) in order to get it to work.
If you switch your DI library more often than you switch loggers then don't bother with it. But if you're like me and use Ninject in almost every project, then it's a nice way to decouple your code from any specific logging library.

If you want to use dependency injection via the constructor you can pass the ILoggerFactory interface.
This is how I did it.
using Ninject.Extensions.Logging;
public class MyClass
{
private readonly ILogger _log;
public MyClass(ILoggerFactory logFactory)
{
_log = logFactory.GetCurrentClassLogger();
}
public void DoWork()
{
_log.Info("Doing work!");
}
}
Problem solved!
Hope this helps someone.

Related

Asp.net core 2.0 AutoMapper IValueResolver dependency injection

I have tried most of the examples in the Google Results, Stackoverflow and in AutoMapper. But was not able to get the IValueResolverdependancy injection to work.
I have below service
public class StorageService : IStorageService
{
private readonly BlobServiceSettings _blobServiceSettings;
public StorageService(IOptions<BlobServiceSettings> blobServiceSettings)
{
_blobServiceSettings = blobServiceSettings.Value;
}
// some methods I need
}
This is my profile
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<Building, BuildingEnvelope>(MemberList.None)
.ForMember(dest => dest.ImageUrl, opt => opt.ResolveUsing<BuildingImageUrlResolver>());
}
}
this is my IValueResolver
public class BuildingImageUrlResolver : IValueResolver<Building, BuildingEnvelope, string>
{
private readonly IStorageService _storageService;
public BuildingImageUrlResolver(IStorageService storageService)
{
_storageService = storageService;
}
public string Resolve(Building entity, BuildingEnvelope envelope, string member, ResolutionContext context)
{
return _storageService.MyMethod(entity.ImageFileName);
}
}
I get the below error in my inner exception
No parameterless constructor defined for this object.
Not sure what I am doing wrong.
Thanks in advance
Neo
Lucian's suggestion is correct -- the AutoMapper.Extensions.Microsoft.DependencyInjection package is the way to go. Even if you don't want to use it, you'll have to do something similar.
I've had this very same problem and by using the extensions, you just modify the entrypoint from which you register AutoMapper and its configuration.
What the extensions do (source) is:
Initializes Automapper with the configuration provided
It scans for all classes you have that you could be implementing with dependency injection and registers them as transient, looking for implementations of the following:
IValueResolver
IMemberValueResolver
ITypeConverter
IMappingAction
The assemblies that it will scan actually depend on the parameters that you provide on the call.
If any of these can be actually instantiated, then they will be registered as transient implementation.
And just like that, AutoMapper will request instances of these to the service provider, which will resolve them, and to do that, it will also resolve any pending dependencies.
Note that this is actually very simple -- the most difficult part is scanning the right assemblies and registering the right classes. You can do it manually too, but these extensions already take care of it for you.
Mind you, even when reflection has been improved a lot, this process is relatively slow, so try not to abuse it too much (for instance, in tests).
Finally, if none of that works for you, remember that you need to setup AutoMapper to use the dependency injection resolver too:
automapperConfiguration.ConstructServicesUsing(serviceProvider.GetService);

Guice multiple implementations, parameterized constructor with dependencies

I'm struggling with a particular dependency injection problem and I just can't seem to figure it out. FYI: I'm new to guice, but I have experience with other DI frameworks - that's why I believe this shouldn't be to complicated to achieve.
What am I doing:
I'm working on Lagom multi module project and using Guice as DI.
What I would like to achieve:
Inject multiple named instances of some interface implementation (lets' call it publisher, since it will publishing messages to kafka topic) to my service.
This 'publisher' has injected some Lagom and Akka related services (ServiceLocator, ActorSystem, Materializer, etc..).
Now I would like to have two instances of such publisher and each will publish messages to different topic (So one publisher instance per topic).
How would I achieve that?
I have no problem with one instance or multiple instances for the same topic, but if I want to inject different topic name for each instance I have a problem.
So my publisher implementation constructor looks like that:
#Inject
public PublisherImpl(
#Named("topicName") String topic,
ServiceLocator serviceLocator,
ActorSystem actorSystem,
Materializer materializer,
ApplicationLifecycle applicationLifecycle) {
...
}
If I want to create one instance I would do it like this in my ServiceModule:
public class FeedListenerServiceModule extends AbstractModule implements ServiceGuiceSupport {
#Override
protected void configure() {
bindService(MyService.class, MyServiceImpl.class);
bindConstant().annotatedWith(Names.named("topicName")).to("topicOne");
bind(Publisher.class).annotatedWith(Names.named("publisherOne")).to(PublisherImpl.class);
}
}
How would I bind multiple publishers each for it's own topic?
I was playing around with implementing another private module:
public class PublisherModule extends PrivateModule {
private String publisherName;
private String topicName;
public PublisherModule(String publisherName, String topicName) {
this.publisherName = publisherName;
this.topicName = topicName;
}
#Override
protected void configure() {
bindConstant().annotatedWith(Names.named("topicName")).to(topicName);
bind(Publisher.class).annotatedWith(Names.named(publisherName)).to(PublisherImpl.class);
}
}
but this led me nowhere since you can't get injector in you module configuration method:
Injector injector = Guice.createInjector(this); // This will throw IllegalStateException : Re-entry is not allowed
injector.createChildInjector(
new PublisherModule("publisherOne", "topicOne"),
new PublisherModule("publisherTwo", "topicTwo"));
The only solution which is easy and it works is that I change my PublisherImpl to abstract, add him abstract 'getTopic()' method and add two more implementations with topic override.
But this solution is lame. Adding additional inheritance for code reuse is not exactly the best practice. Also I believe that Guice for sure must support such feature.
Any advises are welcome.
KR, Nejc
Don't create a new Injector within a configure method. Instead, install the new modules you create. No child injectors needed—as in the PrivateModule documentation, "Private modules are implemented using parent injectors", so there's a child injector involved anyway.
install(new PublisherModule("publisherOne", "topicOne"));
install(new PublisherModule("publisherTwo", "topicTwo"));
Your technique of using PrivateModule is the one I'd go with in this situation, particularly given the desire to make the bindings available through binding annotations as you have it, and particularly if the full set of topics is known at runtime. You could even put the call to install in a loop.
However, if you need an arbitrary number of implementations, you may want to create an injectable factory or provider to which you can pass a String set at runtime.
public class PublisherProvider {
// You can inject Provider<T> for all T bindings in Guice, automatically, which
// lets you configure in your Module whether or not instances are shared.
#Inject private final Provider<ServiceLocator> serviceLocatorProvider;
// ...
private final Map<String, Publisher> publisherMap = new HashMap<>();
public Publisher publisherFor(String topicName) {
if (publisherMap.containsKey(topicName)) {
return publisherMap.get(topicName);
} else {
PublisherImpl publisherImpl = new PublisherImpl(
topicName, serviceLocatorProvider.get(), actorSystemProvider.get(),
materializerProvider.get(), applicationLifecycleProvider.get());
publisherMap.put(topicName, publisherImpl);
return publisherImpl;
}
}
}
You'd probably want to make the above thread-safe; in addition, you can avoid the explicit constructor call by using assisted injection (FactoryModuleBuilder) or AutoFactory, which will automatically pass through explicit parameters like topicName while injecting DI providers like ServiceLocator (which hopefully has a specific purpose, because you may not need much service-locating within a DI framework anyway!).
(Side note: Don't forget to expose your annotated binding for your PrivateModule. If you don't find yourself injecting your topicName anywhere else, you might also consider using individual #Provides methods with the assisted injection or AutoFactory approach above, but if you expect each Publisher to need a differing object graph you might choose the PrivateModule approach anyway.)
Guice's approach to dependency injection is that the DI framework complements your instantiation logic, it doesn't replace it. Where it can, it will instantiate things for you, but it doesn't try to be too clever about it. It also doesn't confuse configuration (topic names) with dependency injection - it does one thing, DI, and does that one thing well. So you can't use it to configure things, the way you can with Spring for example.
So if you want to instantiate an object with two different parameters, then you instantiate that object with two different parameters - ie, you invoke new twice. This can be done by using provider methods, which are documented here:
https://github.com/google/guice/wiki/ProvidesMethods
In your case, it might look something like adding the following method to your module:
#Provides
#Named("publisherOne")
#Singleton
Publisher providePublisherOne(ServiceLocator serviceLocator,
ActorSystem actorSystem,
Materializer materializer,
ApplicationLifecycle applicationLifecycle) {
return new PublisherImpl("topicOne", serviceLocator,
actorSystem, materializer, applicationLifecycle);
}
Also, you probably want it to be a singleton if you're adding a lifecycle hook, otherwise you could run into memory leaks each time you add a new hook every time it's instantiated.

asp.net core build-in dependency injection long code

In our previous app we used StructureMap and we could write very little code.
before every service we added the dependencies like:
[SetterProperty]
public IXService XService { get; set; }
and in the constructor
ObjectFactory.BuildUp(this);
then in test we could instantiate it simply by
var service = new XService();
Now, we start another app and using asp.net core build-in DI container.
it look like we should write a lot of code, and very long constructor for each test:
private readonly ILogger<AccountsController> _logger;
private readonly IMapper _mapper;
private readonly IAccountBlService _accountBlService;
private readonly IValidationHelper _validationHelper;
private readonly IValidator<AccountDTO> _accountDTOValidator;
private readonly Example _example;
private readonly IConfiguration _configuration;
public AccountsController(BillingContext context, ILogger<AccountsController> logger, IMapper mapper, IAccountBlService accountBlService,
IValidationHelper validationHelper, IValidator<AccountDTO> accountDTOValidator, IOptions<Example> example, IConfiguration configuration)
{
_logger = logger;
_mapper = mapper;
_accountBlService = accountBlService;
_validationHelper = validationHelper;
_accountDTOValidator = accountDTOValidator;
_configuration = configuration;
_example = example.Value;
}
Is there a shorter way we didnt found? is one planned for the near future? should we use StructureMap instead the built-in container? or there are disadvantages for this? thanks!
Is there a shorter way we didnt found?
In short: No, not with the default container. But I recommend you read Dependency Injection in .NET by Mark Seemann (if you have then please ignore me saying this), because have you heard of "Composition Root"? IMHO the way you declared dependencies has the same amount of code, just scattered all over your code base. While you should really keep it in one place for maintainability.
Is one planned for the near future? Not that I know of, but really if you look at it, it's the same amount of code, just centralized. We however use NServiceBus's ability to call "RegisterComponents" on the BusConfiguration which uses reflection to register all dependencies in one call. You could look for containers that can do the same. Now if you're thinking about your tests, if you use XUnit you can set up your SUT via de test class's constructor. Refactor it in factory classes so you only have to write it once. This way you can also throw mocks in to keep your tests clean.
Should we use StructureMap instead the built-in container?
If you wish. We use Autofac.
Or are there disadvantages for this?
Not that we've encountered thus far. Sometimes you need the IServiceProvider for special 'tricks' but there's always a way.
Note: if you are concerned about having 7 dependencies in your controller (which is a lot indeed) there are a few options:
Look at the scope of the dependency. If it's only used in 1 or 2 action methods you can also declare it [FromService] in the action method's signature
Is your controller doing too much? Watch out for god classes. Maybe it needs refactoring. After all, controllers are nothing more than logical collections of action methods.
Can dependencies be combined? Sometimes it seems they need to be seperated, but in most contexts they are always in pairs. It appears there's a high cohesion and you could combine them in a helper class to maintain cohesion.

Castle Windsor Property Injection with paramters

I am new to this so I appreciate the help. I am using Castle Windsor as my container with XML config. For several of my core services this works perfectly, I simply declare a public property named the same thing and it injects it as expected. Most of my core services have no-arg constructors, those ones work out of the box. But what about if I have a core service that itself has it's own dependencies, how best to deal with that? For example, say I have a configurable message queuing service:
public interface IQueueService {
void SendMessage(string msg);
}
public class SQSService : IQueueService {
private ServiceConfig _config;
public SQSService(ServiceConfig config) {
_config = config;
}
public void SendMessage(string msg){
//do message stuff
}
}
SQSService itself requires a config to initialize properly (endpoint, port, etc). Is there an easy way to configure the DI to resolve this config? Or am I better off re-factoring the SQSService to not have this dependency?
When injecting something that is dependent on a config, session, request, etc., you have the flexibility to break away from making your dependency object have the same structure as the underlying source (in fact, you should as much as possible, otherwise you may end up accidentally writing code that implicitly depends on that structure). Inject the properties you need, rather than the config itself. I am not sure how to accomplish this using the XML config, but I know the fluent API allows for injection using .FromAppSettings(), or you can use the web/app.config to house your config, using .FromAppConfig() as explained here:
How to instantiate a class based on web.config file with Castle Windsor?

Error Logging in Asp.net mvc app inside web application or domain layer?

I just want to know what would be best practice/ widely used, I currently do my logging in the domain service layer, however anything that happens inside my web application layer is not logged.
I would like one centralized and simple location to do all my create/delete/update loggging...
I have heard of Elmah, not sure how useful it is for domain service layer logging only...
I currently do not use any framework for logging at all, I just string builder my log message or get the exception and flush it into the database... Is this the best way to go about it?
If it matters... I need to use Ninject to inject in my ILoggingService
NOTE: I am not talking about Logging User Activity... that will definetly reside only inside my domain service layer...
Haroon,
Leverage Ninject to create and manage the lifetime of an ILoggingService. The implementation of that service should be built directly on top of a well tested logging library like NLog or log4net.
Once you have an instance of the service, you can easily inject it into either you MVC controller or your domain layer. All logging should happen against that instance, not a static logging class.
This will allow you to have the unified logging you are looking for, with a clean separation of concerns.
imho logging should not be injected. The reason is that most of your services (if not all) will use logging.
If you look at most logging frameworks (like nlog), they are using a singleton/facade and abstract factories to provide logging.
Something like:
public static class LogFactory
{
private static ILogFactory _instance;
public void Assign(ILoggingFactory factory)
{
_instance = factory;
}
public ILogger CreateFor<T>()
{
return _instance.CreateFor<T>();
}
}
The design makes your services only dependent of one class and one interface. Thus it's still extremely easy to switch logging implementations.
In your class use the code like:
public class ServiceImp : IService
{
private ILogger _logger = LogFactory.CreateFor<IService>();
public void SomeMethod()
{
_logger.Warning("Something went wrong, but we can handle it. Hence only a warning");
}
}

Resources