我怎样才能充实对象组成StructureMap,而不必调用setter注入? [英] How can I enrich object composition in StructureMap without invoking setter injection?

查看:209
本文介绍了我怎样才能充实对象组成StructureMap,而不必调用setter注入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图建立 IHttpControllerActivator 接口的实现与带有StructureMap,这样我就可以解决一个控制器,它呈现出相关性的相关的的Htt prequestMessage 正在对MVC的Web API管线处理。

I'm trying to build an implementation of the IHttpControllerActivator interface for with with StructureMap, so that I can resolve a dependency of a controller which takes a dependency on the HttpRequestMessage being processed in the MVC Web API pipeline.

我实施创建如下:

public IHttpController Create(
    HttpRequestMessage request,
    HttpControllerDescriptor controllerDescriptor,
    Type controllerType)
{
    return (IHttpController)this.Container
        .With(request)
        .With(controllerDescriptor)
        .GetInstance(controllerType);
}

集装箱属性是对StructureMap引用的IContainer 它被创建时的实例传递给激活。

The Container property is a reference to the StructureMap IContainer instance passed to the activator when it is constructed.

我对控制器注册使用反射来获取所有 ApiController 实施

My registration for the controllers uses reflection to obtain all the ApiController implementations:

foreach(var controller in this.GetType().Assembly.GetTypes()
    .Where(type => typeof(ApiController).IsAssignableFrom(type)))
{
   this.For(controller).Use(controller);
}

使用调试器,我检查了初始化控制器的实例并传递它们的依赖。然而,当 ExecuteAsync 方法被调用的控制器上,则抛出异常:

Using the debugger, I checked that initialises the controller instances and passes in their dependencies. However, when the ExecuteAsync method is called on the controller, an exception is thrown:

不能重​​用ApiController实例。 'ApiController'具有每传入消息来构造。检查您的自定义IHttpControllerActivator,并确保它不会制造相同的实例。

Cannot reuse an 'ApiController' instance. 'ApiController' has to be constructed per incoming message. Check your custom 'IHttpControllerActivator' and make sure that it will not manufacture the same instance.

在一些挖掘和实验,我发现,这是由于在 ExecuteAsync 开始执行检查这检查请求的属性 ApiController ,看它是否已被分配一个值。如果属性有一个非空值,则认为该控制器已被用来处理请求并中止运行。

After some digging and experimentation I discovered this is due to a check performed at the start of ExecuteAsync which checks the Request property of the ApiController to see if it has been assigned a value. If the property has a non-null value, it infers that the controller has already been used to process a request and aborts the operation.

继此,我验证了StructureMap试图利用它的setter方法​​的注射行为构成控制器时,并负责请求具有非空值。

Further to this, I verified that StructureMap attempted to use its setter-injection behaviour when composing the controller and is responsible for Request having a non-null value.

在我的注册表,我未配置任何setter方法​​的注射,所以我很困惑,为什么它被调用这里。围绕StructureMap API捅还没有产生任何明显的答案,我怎么可能改变表现出的行为。

In my registry, I haven't configured any setter-injection, so I'm confused as to why it's being invoked here. A poke around the StructureMap API hasn't yielded any obvious answers as to how I could change the behaviour exhibited.

我是不是调用StructureMap不正确?是否有一个配置设置,我可以利用说从来没有分配属性值?

Am I invoking StructureMap incorrectly? Is there a configuration setting I can leverage to say "never ever assign a property value"?

推荐答案

我想围绕你与 StructureMap 设置你的控制器的方式您的问题转。为了得到这个工作正常,最好的方法是通过创建自己的实现的IDependencyResolver 的挂钩到的WebAPI堆栈的依赖注入堆栈。有这样的的http://craigsdevspace.word$p$pss.com/2012/02/26/using-structuremap-with-web-api/

I think your issue revolves around the way that you are setting up your controllers with StructureMap. In order to get this working correctly, the best way is to hook into the WebAPI stack's dependency injection stack by creating your own implementation of IDependencyResolver. There's a pretty good example of this at http://craigsdevspace.wordpress.com/2012/02/26/using-structuremap-with-web-api/

基本code,虽然可能看起来是这样的:

The basic code, though, might look something like:

的IDependencyResolver

public class _DependencyResolver : _DependencyScope, IDependencyResolver {

    public _DependencyResolver(IContainer container) : base(container) { }

    public IDependencyScope BeginScope() {
        return new _DependencyScope(_container);
    }
}

IDependencyScope

public class _DependencyScope : ServiceLocatorImplBase, IDependencyScope {
    protected readonly IContainer _container;

    public _DependencyScope(IContainer container) {
        if (container == null)
            throw new ArgumentNullException("container");

        _container = container;
    }

    public override object GetService(Type serviceType) {
        if (serviceType == null)
            return null;

        try {
            return (serviceType.IsAbstract || serviceType.IsInterface)
                ? _container.TryGetInstance(serviceType)
                : _container.GetInstance(serviceType);
        } catch {
            return null;
        }
    }

    protected override object DoGetInstance(Type serviceType, string key) {
        if (string.IsNullOrEmpty(key))
            return _container.TryGetInstance(serviceType);

        return _container.TryGetInstance(serviceType, key);
    }

    protected override IEnumerable<object> DoGetAllInstances(Type serviceType) {
        return _container.GetAllInstances<object>().Where(s => s.GetType() == serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType) {
        return _container.GetAllInstances<object>().Where(s => s.GetType() == serviceType);
    }

    public void Dispose() {
        //_container.Dispose();
    }

}

要挂钩这些类最多的WebAPI,那么,你将以下添加到的Global.asax

To hook these classes up to WebAPI, then, you would add the following to Global.asax:

GlobalConfiguration.Configuration.DependencyResolver = 
    new _DependencyResolver(ObjectFactory.Container);

和无论是在的Global.asax 或你的引导程序,可以添加以下内容:

And either in Global.asax or in your Bootstrapper, you would add the following:

ObjectFactory.Initialize(x => {
    x.Scan(scanner => scanner.AddAllTypesOf<ApiController>());
});

此设置您的 StructureMap 实施使用堆栈的pre-现有的注入结构 - 这应该避免您遇到的问题

This sets up your StructureMap implementation to use the stack's pre-existing injection structure - which should avoid the problem that you're having.

这篇关于我怎样才能充实对象组成StructureMap,而不必调用setter注入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆