Is it possible to have a property on a singleton object that has a different scope? - structuremap

I have the following object:
CommandA (Singleton)
IFoo Foo (PerRequest)
I would like a proxy object to be injected into the singleton so that when I call Foo, it will give me the foo object that is specific to my request.
Is this possible?

By design, all injections in a singleton should be singleton.
First of all, if you CommandA is singleton, the injected objects would be singleton.
Now if you say you need a new object per request, you would probably have a Factory (Singleton) in your CommandA which would create a new object or get proxy reference upon each call.
Hope that helps!

As Anshu says, it sounds like you're really after a factory bahaviour. One way to implement it would be like this:
The command:
public class Command : ICommand
{
private Func<IFoo> _fooProvider;
public Command(Func<IFoo> fooProvider){ _fooProvider = fooProvider; }
public IFoo Foo { get{ return _fooProvider(); }}
}
In your configuration:
For<ICommand>().Singleton().Use<Command>();
For<IFoo>().Use<Foo>();
StructureMap will automatically inject the Func, since the IFoo is configured.

Related

Play Framework: Dependency Injection inside Action

Short version: how to inject an object inside Action in Play Framework?
Long version: In my project I have custom annotation action #AuthenticationRequired which loads User object from the database and puts it into context.args. It uses DAO class that implements UserDAO. Now I want to use DAO class injected into Action by Google Guice. I can use Guice and inject instances in controllers and tests, but I have difficulties injecting DAO class inside Action.
Injector is a field on GlobalSettings instance.
I tried to override GlobalSettings#onRequest() and put UserDAO instance to context.args and then retrieve it from inside AuthenticationRequired action, but it turns out that Action returned by GlobalSettings#onRequest() being called last in the chain of action used with #With and/or custom annotations, so, it is to late.
I also tried to inject DAO instance by annotating action constructor, but but it uses no-args constructor to create an instance of action.
Any ideas how can I achieve this?
For play 2.5 you can simply add #Inject on top of the constructor of Action class and inject whatever needed. Here is a snippet from my working project (I'm using Guice as DI):
public class ChannelPermissionAction extends Action<ChannelPermission> {
private final AuthorizationService authorizationService;
private final AsyncHelper asyncHelper;
#Inject
public ChannelPermissionAction(AuthorizationService authorizationService, AsyncHelper asyncHelper) {
this.authorizationService = authorizationService;
this.asyncHelper = asyncHelper;
}
...
}
You can achieve this just the same as with controllers - describe your action as (a bean in my case - i'm using spring IoC) a dependency and get it called by
public <A> A getControllerInstance(Class<A> clazz)
of Application Global object. That's all you need - you'r dependencies would be injected.
BTW. Actions need to be created with each instance so in my case I should use "prototype" scope.
Mind it while using Guice - it should have similar functionality.

fakeiteasy initializing private members in constructor

I want to test methods in my controller, I know about this...
myController = new MyController();
A.CallTo(()=>myController.SomeMethodIWantToTest().Returns(someValueIAmTesting);
The problem is that inside that parameterless constructor, I call numerous methods in other assemblies that set values for private members,
public class MyController : Controller {
private ILoginBusiness loginBusiness;
private ISomethingElse somethingElse;
//... and so on...
public MyController(){
loginbusiness = ServiceFactory.GetLoginBusiness();
somethingElse = //some method in another assembly that initializes the value
//... and so on, calling methods in other assemblies that initialize the private members...
}
public ActionResult SomeMethodIWantToTest(){ }
}
So how do I isolate all those method calls in my constructor (so I'm not calling methods in those other assemblies?)
First,
myController = new MyController();
A.CallTo(()=>myController.SomeMethodIWantToTest().Returns(someValueIAmTesting);
Will result in an error, as A.CallTo only handles calls to fakes (and there should be an extra ) after …ToTest()).
Second, the general approach that is taken in this sort of situation is called Dependency Injection. Instead of having a class make all its dependencies (in your case, by calling methods from other assemblies), you have its dependencies provided to it.
Assuming you're able to start injecting dependencies, you're almost home. You're already relying on interfaces inside MyController, so then you can use FakeItEasy to supply fakes to MyController, avoiding calls to the out-of-assembly methods.

How to access instance properties of MvcApplication class inside request context?

Inside controller action you can:
MvcApplication app = this.HttpContext.ApplicationInstance as MvcApplication;
But this.HttpContext.ApplicationInstance only holds the superclass, not the derived class declared in Global.asax. Therefore any instance properties you declared there, are null;
Is there a way around this? Shouldn't there be a way to access the derived app class?
I'd like to have instances (of my helper classes), stored as instance properties inside the application instance, rather than having them as static classes.
Or do static helpers, hold no drawbacks?
There is a way around this and you've already written it:
MvcApplication app = this.HttpContext.ApplicationInstance as MvcApplication;
If you don't like that, try changing your MvcApplication class to:
public class MvcApplication : HttpApplication
{
public static MvcApplication Instance
{
get
{
// Current could be null, depending on the caller
return HttpContext.Current != null
? HttpContext.Current.ApplicationInstance
: null;
}
}
}
Then you can access your application as MvcApplication.Instance. Be cautious that Instance is not null.
Late answer (but for anyone in need of assistance).
I had this issue as well.
I think you can use the Application["myKey"] array, to set some values. Sure they aren't instance properties, but you can set a dependency injection container (like unity, who recommends this option in their code sample) , then access it from your controller with Application["myKey"].
From http://msdn.microsoft.com/en-us/library/ms178473%28VS.80%29.aspx
You should set only static data during application start. Do not set
any instance data because it will be available only to the first
instance of the HttpApplication class that is created.
There is no harm in using single static class, because your code becomes portable to non web project as well.
Ideally, instead of static properties, you can create MyApp class and wrap all app specific global data and other utility methods. And either you can create a static instance property and store instance of MyApp in HttpContext.Current.Application which is globally accessible in each request.
I think you are not aware that HttpApplication class is reused, and I suspect that your some handler is cleaning the properties.

How to inject with Guice when there are two different constructors?

Total Guice noob here, have read a few articles and seen the intro video, that's about it.
Here's my simplified old code that I'm trying to "guicifiy". Can't quite figure out how to, since (as far as I understand), I can only #inject-annotate one of the two constructors? How can a calling class create the one or the other instance? Or will I have to refactor this somehow?
public class MyDialog extends JDialog {
public MyDialog( JFrame parent, <other parameters...> ) {
super( parent );
}
public MyDialog( JDialog parent, <other parameters...>) {
super( parent );
}
}
You can only inject into the one ctor.
Depending on how this class is being used, you could:
Inject a factory into the client code with two "new" methods.
Roll all the arguments into one ctor and pass null when not required.
How can a calling class create the one or the other instance?
This suggests that the calling classes will want multiple instances of MyDialog? Then you need to use a hand-rolled factory (Assisted Inject can handle this for you if you only had one ctor). I don't know the details of what you are up to and I'm likely repeating what you already know but as a blanked statement I'd suggest also extracting an interface from MyDialog and have the factory return them. This way you can fake MyDialog in tests.
Constructor injection is very clean. mlk is right, saying that you can inject into one constructor only.
What you can do is use method injection:
public class Smt {
private int a;
private Cereal cereal;
private Personality personality;
private ignition;
public Smt() {
this.a = 5;
}
public Smt(int a) {
this.a = a;
}
#Inject
public void setup(#CiniMini Cereal cereal, #Rastafarian Personality personality,
Ignition ignition) {
this.cereal = cereal;
this.personality = personality;
this.ignition = ignition;
}
}
What Guice will do is call your class' setup class method and provide all the injections. Then you do the same thing as in the constructor--assign the objects to your class' attributes.
I agree with the previous comments.
Just an additional hint: constructor injection is supposed to provide all dependencies a class needs. As mlk says, one approach could be to annotate the constructor with most arguments and then refactor the other one to call the former by passing null values where needed.
Additionally, Guice 3.0 supports the so called Constructor Bindings which allow the programmer to specify which constructor to use. See here for more details.

Is there a good/proper way of solving the dependency injection loop problem in the ASP.NET MVC ContactsManager tutorial?

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.

Resources