Soft-code ILogger in HostManager and InternalDependencyResolver - openrasta

I created my own ILogger implementation and register an instance via
ResourceSpace.Uses.Resolver.AddDependencyInstance<ILogger>(...)
inside the
using (OpenRastaConfiguration.Manual)
block.
This works fine for most log messages, however some classes in OpenRasta try to figure out their ILogger instance before the DI is ready, like HostManager:
static HostManager()
{
Log = DependencyManager.IsAvailable
? DependencyManager.GetService<ILogger>()
: new TraceSourceLogger();
}
In my case (and I suspect the general case), IsAvailable is false, so it defaults to TraceSourceLogger.
As static ILogger HostManager.Log is not a public property, I hacked it and made it public so that I can now set it.
When it comes to InternalDependencyResolver, which is always initialized to new TraceSourceLogger() on object construction, it does have a publicly settable ILogger Log property, so I could just use that.
Now all of OpenRasta's log messages that I've encountered so far go to my custom ILogger.
Does anyone know of a way to get all of OpenRasta's classes (I did not check systematically and might have missed a class or two) to log to a custom ILogger without having to hack the sources? (It's always nice to know that upgrading OpenRasta won't require repatching and rebuilding)

as you found out, it's an ordering issue. Happy to take a patch to fix that though.

Related

How do I set a global error handler without overriding existing RabbitListenerContainerFactory in Spring AMQP?

I have a situation where there are many downstream projects using a same common library holding the RabbitMQ configuration.
I want to add a global error handler in such common configuration but pretty much all online documentation says that I have to declare my own RabbitListenerContainerFactory so that I can set my error handler in the bean definition code (e.g. via autowiring a SimpleRabbitListenerContainerFactoryConfigurer whose by the way I haven't fully understood the purpose).
However, I don't want to override any existing RabbitListenerContainerFactory, because some of the downstream projects declare their own implementation of it, and I don't want to go and set my global error handler for each of them. I want to declare the global error handler only in the common library and once for all.
How can I do that by using the existing implementation of RabbitListenerContainerFactory whatever that is?
Seems like I have found a working solution.
#Configuration
public class SimpleRabbitListenerContainerFactoryExtraConfig {
public SimpleRabbitListenerContainerFactoryExtraConfig(
final SimpleRabbitListenerContainerFactory factory,
final MyErrorHandler handler) {
factory.setErrorHandler(handler);
}
}

How to use DI inside a static Method in Asp.net Core rc1

I see defaut template use ServiceProvder.GetService<ApplicationDbCotnext>() to initialize a DbContext,
But when you inside a Static Method, I have no idea how to get a DbContext, because there is no ServiceProvider.
Is there a way to get the ServiceProvider ?
Well, first of all, this has nothing to do with asp.net-core per se. This has more to do with how Dependency Injection works. You have to ask yourself why your method is static. Is that really necessary?
If you can't get rid of your static method, you might as well go all the way and introduce another anti-pattern, the Service Locator Pattern. In short: In the Startup class you put a reference to the ServiceProvider in a static property (call it for instance "ServiceProviderSingleton") of a static class (for instance "ServiceProviderProvider"). This way you can just call "ServiceProviderProvider.ServiceProviderSingleton.GetService()".
Again, i suggest giving your overal design a critical look. But if this is what you need/want then I hope it helped.
If we have a look at Microsoft's static methods (extension) - they seem not to use logging there - just throw appropriate Exception, for example in UseMvc method (for StartUp class):
https://github.com/aspnet/Mvc/blob/760c8f38678118734399c58c2dac981ea6e47046/src/Microsoft.AspNetCore.Mvc.Core/Builder/MvcApplicationBuilderExtensions.cs

Specifying which concrete type to retrieve

I am looking at structuremap as an IOC/DI tool. Looking at this example:
http://docs.structuremap.net/QuickStart.htm
The only thing that does not make sense is, if I have an interface and derive several concrete types from it, in the code:
public class ClassThatGetsAnIValidator
{
public void SaveObject(object objectToSave)
{
// Go get the proper IValidator from StructureMap
IValidator validator = ObjectFactory.GetInstance();
var notification = validator.Validate(objectToSave);
if (notification.IsValid())
{
// save the object
}
}
}
How do I know which validator I get? IE I may have an AlphaBetValidator, NumericValidator, etc, with different method bodys and so on.....
I think this is the point:
Registering "what" and "how" StructureMap should build or find those requested services (the tedious part, but it's gotten much better over the years)
Which I struggle to grasp.
Please help.
Thanks
From the documentation:
If there is only one Instance for a registered PluginType, that
Instance will be assumed to be the default for the PluginType.
Otherwise, if there is more than one Instance for a PluginType,
StructureMap must be explicitly told which Instance is the default,
otherwise the call to GetInstance() will throw an exception (202).
To resolve to a particular instance you could use the naming mechanism. From the same documentation page:
Sometimes it's advantageous to retrieve a "named" instance of a type.
Let's say that you're building a system that needs to connect to
interface with multiple external shipping systems. You've designed an
interface for your system called IShippingSystem that hides the
details of each external shipping behind adapters. The rest of your
code should only "know" how to interact with the IShippingSystem, but
at some point, some class needs to know how to select and retrieve the
proper instance of IShippingSystem. Before the advent of IoC
containers like StructureMap, you would have coded a Factory class and
possibly a Builder class by hand to do the construction. With
StructureMap, this code is simply a call to the
ObjectFactory.GetNamedInstance(Type, string) method.
IShippingService internationalService = ObjectFactory.GetNamedInstance<IShippingService>("International");
IShippingService domesticService = ObjectFactory.GetNamedInstance<IShippingService>("Domestic");

Unity Container ResolutionFailedException when the mapping is correct in the config file

I was using a ServiceLocator which i was DIing with Unity
public ServiceLocator(IUserStore userStore, IProdcutsStore productsStore, ...etc) {}
public IUserStore UserStore
{
get { return userStore; }
}
This all worked fine, but I wanted lazy instantiation of the repositories as they have quite sparse use.
So my ServiceLocator now looks like
public ServiceLocator(IUnityContainer container) {}
public IUserStore UserStore
{
get { return (IUserStore)container.Resolve(typeof(IUserStore)); }
}
// ...etc
I'm now getting a really unhelpful ResolutionFailedException error
Resolution of the dependency failed,
type =
"DomainModel.DataServices.Interface.IUserStore",
name = "". Exception message is: The
current build operation (build key
Build
Key[DomainModel.DataServices.Interface.IUserStore,
null]) failed: The current type,
DomainModel.DataServices.Interface.IUserStore,
is an interface and cannot be
constructed. Are you missing a type
mapping? (Strategy type
BuildPlanStrategy, index 3)
Telling me my interface type cannot be instantiated because it is an interface is pretty pointless. I know it's an interface, that's why the container is supposed to be resolving it for me!
Anyway, the point to note here is that I know the type mapping in the config is fine, as when I was injecting the type interface directly instead of trying to lazy load, it resolved it with no problems.
What am I missing that means something somewhere has to change in order to lazy load this way?
Update: I am guessing what's happening here, is that when I DI the container into the ServiceLocator, the "main" container is instantiating a new container each time which is then not configured properly. I think maybe I need some way to specify that I was to pass this in as the container, rather than resolve it with a new instantiation.
You're going in a somewhat wrong direction... At first you've had a testable class that declared its dependencies in the constructor and you turned it into non-so-testable, asking for "something" inside a container... No good =(
You should either implement some factory interface for your expensive object and require it in the constructor, or (if you can) switch to Unity 2.0 and use the Automatic Factories:
public ServiceLocator(Func<IUserStore> userStoreBuilder)
//...
public IUserStore UserStore
{
get { return userStoreBuilder(); }
}
If you want to only create the instance of that object once, you can add cahcing to that property, or with .NET 4.0 you can try asking Lazy in the constructor.
P.S. Oh, yes. And answering your particualr question =) If you still want to inject an instance of your container somewhere else, you need to first register it inside itself =)
container.RegisterInstance<IUnityContainer>(container);
Fix (see comments) DO NOT register a Unity container inside itself, this will cause StackOverflowException in container.Dispose(), the correct instance will be injected as a dependency without the registration.

How to avoid having injector.createInstance() all over the place when using guice?

There's something I just don't get about guice: According to what I've read so far, I'm supposed to use the Injector only in my bootstrapping class (in a standalone application this would typically be in the main() method), like in the example below (taken from the guice documentation):
public static void main(String[] args) {
/*
* Guice.createInjector() takes your Modules, and returns a new Injector
* instance. Most applications will call this method exactly once, in their
* main() method.
*/
Injector injector = Guice.createInjector(new BillingModule());
/*
* Now that we've got the injector, we can build objects.
*/
RealBillingService billingService = injector.getInstance(RealBillingService.class);
...
}
But what if not all Objects I ever need can be created during startup? Maybe I want to respond to some user interaction when the application is running? Don't I have to keep my injector around somewhere (e.g. as a static variable) and then call injector.getInstance(SomeInterface.class) when I need to create a new object?
Of course spreading calls to Injector.getInstance() all over the place seems not to be desirable.
What am I getting wrong here?
Yes, you basically only should use the Injector to create get the instance for the root-object. The rest of the application shouldn't touch the Guice-Container. As you've noticed, you still need to create some objects when required. There are different approaches for doing that, each suitable for different needs.
Inject a Provider
Provider is a interface from Guice. It allows you to request a new instance of a object. That object will be created using Guice. For example.
class MyService{
private Provider<Transaction> transactionProvider;
public MainGui(Provider<Transaction> transactionProvider){
this.transactionProvider = transactionProvider;
}
public void actionStarted(){
Transaction transaction = transactionProvider.get();
}
Build a Factory
Often you need some kind of factory. This factory uses some injected services and some parameters and creates a new object for you. Then you use this factory for new instances. Then you inject that factory and use it. There also help for this with the AssistedInject-extension
I think with these two possibilities you rarely need to use the Guice-Injector itself. However sometimes is still appropriate to use the injector itself. Then you can inject the Injector to a component.
To extend on the answer Gamlor posted, you need to also differentiate between the object types you are using.
For services, injection is the correct solution, however, don't try to always make data objects (which are generally the leafs in your object graph) injectable. There may be situations where that is the correct solution, but injecting a Provider<List> is probably not a good idea. A colleague of mine ended up do that, it made the code base very confusing after a while. We just finished cleaning it all out and the Guice modules are much more specific now.
In the abstract, I think the general idea is that if responding to user events is part of the capabilities of your application, then, well...
BillingService billingService = injector.getInstance(BillingService.class);
billingService.respondToUserEvent( event );
I guess that might be a little abstract, but the basic idea is that you get from Guice your top-level application class. Judging from your question, I guess that maybe BillingService isn't your top-level class?

Resources