Using ASP.net MVC How to inject? ModelState into service.

304 views
Skip to first unread message

obscured

unread,
Mar 10, 2009, 8:18:51 AM3/10/09
to structuremap-users
Hello,

I was going through the tutorials on Asp.net mvc located here:
http://www.asp.net/learn/mvc/tutorial-29-cs.aspx.

I have managed to use Structuremap as the DI for injecting the
repository and service but only if I do not abstract out the
ModelState dictionary. Here are the relevant snippets to hopefully
outline my question.

// This interface is used to help wrap the modelstatedictionary
public interface IValidationDictionary
{
void AddError(string key, string errorMessage);
bool IsValid { get; }
}

// The concrete implementation
public class ModelStateWrapper : IValidationDictionary
{
private ModelStateDictionary _modelState;

public ModelStateWrapper(ModelStateDictionary modelState)
{
_modelState = modelState;
}

//....Rest of IValidationDictionary interface implementation
}

// This is the service
public class MyService : IMyService
{
private IValidationDictionary _validationDictionary = null;
private IRepository _repository = null;

public MyService(IValidationDictionary validationDictionary,
IRepository repository)
{
_validationDictionary = validationDictionary;
_repository = repository;
}

//...Rest of IMyService interface implementation
}

// Structuremap registry which gets bootstrapped at startup of
application.
ForRequestedType<IRepository>().TheDefaultIsConcreteType<Repository>
();
ForRequestedType<IMyService>().TheDefaultIsConcreteType<MyService>();

Now if I strip out the IValidationDictionary bits this all works
fine. That is, if I leave out the IValidationDictionary from the
service then Structuremap happily injects the service. But with it
in, it complains (I know why it does just can't seem to figure out how
to fix it). This IValidationDictionary would normally be called
indirectly by a controller like so.

public class MyController : Controller
{
private IMyService _service;

public MyController()
{
_service = new MyService(new ModelStateWrapper
(this.ModelState));
}

//......
}

Notice how the ModelStateWrapper is given the ModelState.

So my question is, how to have structuremap inject the service when it
needs an IValidationDictionary whose concrete class requires a
parameter of type ModelStateDictionary. I have tried a number of
different ways, but none seem to work. I thought maybe this would be
a job for EnrichWith or OnCreation. But I can't seem to wrap my head
around it.

So any help would be much appreciated. If any additional information
is required please let me know.

Thank you,
Obscured.

George H.

unread,
Apr 8, 2009, 3:21:20 PM4/8/09
to structuremap-users
Ran into the same question today... a little digging around and I
think I figured it out. Try the following (note, I'm new to
StructureMap so this might not be the right way?):

For your structure map configuration:

ForRequestedType<IValidationDictionary>
().TheDefaultIsConcreteType<ModelStateValidationDictionary>();
ForRequestedType<IRepository>().TheDefaultIsConcreteType<Repository>
();
ForRequestedType<IMyService>().TheDefaultIsConcreteType<MyService>
();

Then inside of your controller, you would have the following:

public class MyController : Controller
{
private IMyService _service;

public MyController()
{
_service = ObjectFactory.With<IValidationDictionary>(new
ModelStateValidationDictionary
(this.ModelState)).GetInstance<IMyService>();
}

public MyController(IMyService service)
{
_service = service;
}

//......
}

That seemed to work for my project which is structured similarly.

George

Eric Hexter

unread,
Apr 8, 2009, 8:01:23 PM4/8/09
to structure...@googlegroups.com
Without seeing exactly what you are doing, it is hard to say but I would make a guess that this is not a great idea.  

I try to stay away from ServiceLocation which is what you are proposing in the constructor at all costs.  I would probably go down the route of passing in the model state to the method that       would use it, inside of the action.

This will allow you to use dependency injection in your controller and keep you controllers container agnostic Which is always a good thing.

Eric
Reply all
Reply to author
Forward
0 new messages