Still lost. I have been reading some info on IOC from a MVC team
member:
http://bradwilson.typepad.com/blog/2010/10/service-location-pt5-idependencyresolver.html
And here:
http://bradwilson.typepad.com/blog/2010/10/service-location-pt10-controller-activator.html
When I asked if I needed to implement the controller activator I got
the following answer:
"You are not required to implement this interface if your DI container
can create arbitrary objects (for example, Unity can do this), since
our fallback strategy is to ask the Dependency Resolver to create the
controller if there is no implementation of IControllerActivator."
Have no idea what arbitrary objects are.
In MVC 3 Preview 1 I was using the "old" IMVCServiceLocator replaced
now by IDependencyResolver:
public class ServiceLocator : IMvcServiceLocator {
const String HttpContextKey =
"__StructureMapServiceLocator_Container";
private readonly IMvcServiceLocator _default;
private readonly IContainer _container;
protected Container Container {
get {
if (!HttpContext.Current.Items.Contains(HttpContextKey)) {
HttpContext.Current.Items.Add(HttpContextKey, Container);
}
return (Container)HttpContext.Current.Items[HttpContextKey];
}
}
public ServiceLocator() {
ServiceLocator locator = MvcServiceLocator.Current as
ServiceLocator;
if (locator != null)
_container = locator.Container;
_default = MvcServiceLocator.Default;
} // ServiceLocator
public ServiceLocator(IContainer container)
: this(container, MvcServiceLocator.Default) {
} // ServiceLocator
public ServiceLocator(IContainer container, IMvcServiceLocator
locator) {
_container = container;
_default = locator;
} // ServiceLocator
public void Release(Object instance) {
if (instance != null)
GC.SuppressFinalize(instance);
} // Release
private object Resolve(Type type, String key = null) {
Object instance = _container.GetInstance(type);
if (instance != null)
return instance;
Object defaultInstance = _default.GetInstance(type, key);
if (defaultInstance != null)
return defaultInstance;
throw new ActivationException(String.Format("Could not resolve
service type {0}.", type.FullName));
} // Resolve
private IEnumerable<Object> ResolveAll(Type type) {
IEnumerable<Object> instances =
_container.GetAllInstances(type).Cast<IEnumerable<Object>>();
if (instances.Count() > 0)
return instances;
var defaultInstances = _default.GetAllInstances(type);
if (defaultInstances != null)
return defaultInstances;
throw new ActivationException(String.Format("Could not resolve
service type {0}.", type.FullName));
} // ResolveAll
public IEnumerable<Object> GetAllInstances(Type serviceType) {
return ResolveAll(serviceType);
} // GetAllInstances
public IEnumerable<TService> GetAllInstances<TService>() {
IEnumerable<Object> instances = ResolveAll(typeof(TService));
return from TService instance in instances select instance;
} // GetAllInstances
public Object GetInstance(Type type, string key) {
return Resolve(type, key);
} // GetInstance
public object GetInstance(Type type) {
return Resolve(type);
} // GetInstance
public TService GetInstance<TService>(String key) {
return (TService)Resolve(typeof(TService), key);
} // GetInstance
public TService GetInstance<TService>() {
return (TService)Resolve(typeof(TService));
} // GetInstance
public Object GetService(Type type) {
return Resolve(type);
} // GetService
} // ServiceLocator
And a ControllerFactory which I think now is not needed because of
ControllerActivador:
public class StructureMapControllerFactory : IControllerFactory {
private readonly IContainer _container;
private readonly IControllerFactory _factory;
public StructureMapControllerFactory(IContainer container)
: this(container, new DefaultControllerFactory()) {
} // StructureMapControllerFactory
public StructureMapControllerFactory(IContainer container,
IControllerFactory factory) {
_container = container;
_factory = factory;
} // StructureMapControllerFactory
public IController CreateController(RequestContext context, String
name) {
try {
return
_container.GetInstance<IController>(name.ToLowerInvariant());
} catch (Exception) {
return _factory.CreateController(context, name);
}
} // CreateController
public void ReleaseController(IController controller) {
GC.SuppressFinalize(controller);
} // ReleaseController
} // ControllerFactory
These are the Release Notes for MVC 3 Beta that concerns IOC:
-------------------------
Building on the
ASP.NET MVC 3 Preview 1 release, the current release
includes added support for two new services and four existing
services, and improved support for dependency resolution and the
Common Service Locator. New IControllerActivator Interface for Fine-
Grained Controller Instantiation
The new IControllerActivator interface provides more fine-grained
control over how controllers are instantiated via dependency
injection. The following example shows the interface:
namespace System.Web.Mvc {
using System.Web.Routing;
public interface IControllerActivator {
IController Create(RequestContext requestContext, Type
controllerType);
}
}
Contrast this to the role of the controller factory. A controller
factory is an implementation of the IControllerFactory interface,
which is responsible both for locating a controller type and for
instantiating an instance of that controller type.
Controller activators are responsible only for instantiating an
instance of a controller type. They do not perform the controller type
lookup. After locating a proper controller type, controller factories
should delegate to an instance of IControllerActivator to handle the
actual instantiation of the controller.
The DefaultControllerFactory class has a new constructor that accepts
an IControllerFactory instance. This lets you apply Dependency
Injection to manage this aspect of controller creation without having
to override the default controller-type lookup behavior.
IServiceLocator Interface Replaced with IDependencyResolver
Based on community feedback, the
ASP.NET MVC 3 Beta release has
replaced the use of the IServiceLocator interface with a slimmed-down
IDependencyResolver interface specific to the needs of
ASP.NET MVC.
The following example shows the new interface:
namespace System.Web.Mvc {
using System.Collections.Generic;
public interface IDependencyResolver {
object GetService(Type serviceType);
IEnumerable<object> GetServices(Type serviceType);
}
}
As part of this change, the ServiceLocator class was also replaced
with the DependencyResolver class. Registration of a dependency
resolver is similar to earlier versions of
ASP.NET MVC:
DependencyResolver.SetResolver(myResolver);
Implementations of this interface should simply delegate to the
underlying dependency injection container to provide the registered
service for the requested type.
When there are no registered services of the requested type,
ASP.NET
MVC expects implementations of this interface to return null from
GetService and to return an empty collection from GetServices.
-------------------------
I have been trying to find a source example with StructureMap 3 and
MVC 3 Beta and no luck.
Does this info helps?
Sorry, I am completely lost on this.
On Oct 30, 5:28 pm, "Elliott O'Hara" <
elliott.oh...@gmail.com> wrote:
> If anyone is familiar with MVC3 IDependencyResolver and knows that I'm
> wrong, please speak up! :)
>
> On Sat, Oct 30, 2010 at 11:27 AM, Elliott O'Hara <
elliott.oh...@gmail.com>wrote:
>
>
>
>
>
>
>
> > Also,
> > I'm not familiar with MVC 3 yet, but it sounds like setting the instance of
> > IDependencyResolver isn't the same as setting a ControllerFactory. The blog
> > is using a Dependency attribute instead of just injecting the dependency
> > (looks like a lot of yucky to me). Note that on the blog you linked to
> > there is no ctor on the controller and the dependency has a setter.
>
> > For poops and giggles, mark the service with that Dependency attribute and
> > see if the no default ctor error goes away.
>
> > If it does, call someone at MS bad names, then go use a Controller factory
> > :)
>
> > /E
>
> > On Sat, Oct 30, 2010 at 10:53 AM, Jeremy D. Miller <
> >
jeremydmil...@yahoo.com> wrote:
>
> >> What Elliot said is correct.
>
> >> Your call to _container.GetAllInstances<Object>() is going to return an
> >> empty array because that just isn't how StructureMap works. That code is
> >> trying to resolve everything that is explicitly registered as an "object,"
> >> which is very likely nothing. StructureMap requires you to *explicitly*
> >> register types and configurations against a targeted "PluginType".
>
> >> You need to be calling to the container as container.GetAllInstances(
> >> serviceType ).
>
> >> Jeremy D. Miller
> >> The Shade Tree Developer <
http://codebetter.com/blogs/jeremy.miller>
> >>
jeremydmil...@yahoo.com
>
> >> ------------------------------
> >> *From:* shapper <
mdmo...@gmail.com>
> >> *To:* structuremap-users <
structure...@googlegroups.com>
> >> *Sent:* Sat, October 30, 2010 9:23:35 AM
> >> *Subject:* [sm-users] Re: Problem with Structure Map in MVC 3 Beta.
> >> > >
structuremap-us...@googlegroups.com<structuremap-users%2Bunsubs
> >>
structuremap-us...@googlegroups.com<structuremap-users%2Bunsubs
cr...@googlegroups.com>