Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用带结构映射的命名会话实例策略的Setter不安全_C#_.net_Asp.net_Dependency Injection_Inversion Of Control - Fatal编程技术网

C# 使用带结构映射的命名会话实例策略的Setter不安全

C# 使用带结构映射的命名会话实例策略的Setter不安全,c#,.net,asp.net,dependency-injection,inversion-of-control,C#,.net,Asp.net,Dependency Injection,Inversion Of Control,我正在使用结构映射,希望将实例(由容器构造)注入控制器的属性中。实例应命名并存储在http会话上下文容器中。 在我的应用程序的前一个版本中,我使用了自定义DI框架,很容易实现以下功能: public class MyController : Controller { [InjectSession("MySessionInstanceKey")] public MyManager Manager {get; set;} } 使用structuremap有什么简单的方法吗或者我可以

我正在使用结构映射,希望将实例(由容器构造)注入控制器的属性中。实例应命名并存储在http会话上下文容器中。 在我的应用程序的前一个版本中,我使用了自定义DI框架,很容易实现以下功能:

public class MyController : Controller
{
    [InjectSession("MySessionInstanceKey")]
    public MyManager Manager {get; set;}
}
使用structuremap有什么简单的方法吗
或者我可以将自定义属性和注入逻辑引入SM框架(以某种方式扩展框架)
请帮助我找到解决这个问题的方法,非常感谢

另外,我找到了临时解决方案,但它增加了控制器与IoC框架的内聚性,并包含大量代码:

private const string ordersBulkManagerKey = "_OrdersBulkManager";
public BulkManager OrdersBulkManager
{
    get
    {
        var manager = Session[ordersBulkManagerKey] as BulkManager;
        if(manager == null)
        Session[ordersBulkManagerKey] = manager
            = ObjectFactory.GetInstance<BulkManager>();
        return manager;
    }
}
private const string ordersBulkManagerKey=“\u OrdersBulkManager”;
公共散货管理器订单散货管理器
{
得到
{
var manager=作为BulkManager的会话[OrdersBulkManager];
if(manager==null)
会话[OrdersBulkManager]=管理器
=ObjectFactory.GetInstance();
退货经理;
}
}

因此,我不想在那里使用ObjectFactory.GetInstance…

有一些关于如何将配置ASP.NET MVC和StructureMap连接在一起的博客文章。(因此,下面的大部分代码都是来自不同帖子的摘要。)

实现这一点的常用方法是声明我们自己的控制器工厂类,这将允许我们通过构造函数注入依赖项。(ASP.NET MVC使用的默认控制器工厂要求存在默认构造函数)

因此,在MyController类中,您将拥有一个接受MyManager参数的构造函数(将由我们自己的控制器工厂类为您注入)

接下来,您将配置ASP.NET MVC并使用这个新的控制器工厂类(我们将其称为StructureMapControllerFactory)

在StructureMapControllerFactory中,我们调用ObjectFactory.GetInstance以返回控制器(前提是我们已经连接了所有依赖项)

希望我的解释是清楚的,但如果不是,请告诉我,我可以进一步解释

顺便说一句,下面的代码片段是一个关于引导代码的示例

public static class Bootstrapper 
{
    public static void ConfigureStructureMap()
    {
        ObjectFactory.Initialize(
         x => x.AddRegistry(new MyApplicationRegistry()));            
    }
}

public class MyApplicationRegistry : Registry
{
    public MyApplicationRegistry()
    {
         ForRequestedType<ISomeService>()
         .CacheBy(InstanceScope.Your_Choice_Here)
         .TheDefault.Is.OfConcreteType<SomeService>();
    }
}
公共静态类引导程序
{
公共静态void ConfigureStructureMap()
{
ObjectFactory.Initialize(
x=>x.AddRegistry(新的MyApplicationRegistry());
}
}
公共类MyApplicationRegistry:注册表
{
公共MyApplicationRegistry()
{
ForRequestedType()
.CacheBy(InstanceScope.Your_Choice_Here)
.TheDefault.Is.of ConcreteType();
}
}

注:各种选项请参见StructureMap文档

StructureMap可以控制对象的生命周期,因此您不必自己实现它

For<IBulkManager>()
    .LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.HttpSession))
    .Use<BulkManager>();
() .LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.HttpSession)) .使用(); 所以你的代码会变成

public IBulkManager OrdersBulkManager
{
    get { return ObjectFactory.GetInstance<IBulkManager>(); }
}
public IBulkManager OrdersBulkManager
{
get{return ObjectFactory.GetInstance();}
}

谢谢Jon,看来逻辑的生命周期和范围部分已经从我的控制器中消失了,这很好。对ObjectFactory的引用仍然存在,但我真的不在乎,那是大约8个月前。。哈哈,也许将DI容器与代码的其余部分绑定在一起不是一种好的方式。。。但我的属性注入示例也是同样糟糕的样式。因此:我可能应该将生命周期定义与构造函数注入技术一起用于属性设置器有时您可能会发现,由于您的对象并不总是需要它们,因此将BulkManager作为您的控制器作为客户端的服务可能更有意义(这样您的控制器中就根本没有此属性)谢谢你,伙计!构造函数注入+生命周期管理=这就是我需要的
public static class Bootstrapper 
{
    public static void ConfigureStructureMap()
    {
        ObjectFactory.Initialize(
         x => x.AddRegistry(new MyApplicationRegistry()));            
    }
}

public class MyApplicationRegistry : Registry
{
    public MyApplicationRegistry()
    {
         ForRequestedType<ISomeService>()
         .CacheBy(InstanceScope.Your_Choice_Here)
         .TheDefault.Is.OfConcreteType<SomeService>();
    }
}
For<IBulkManager>()
    .LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.HttpSession))
    .Use<BulkManager>();
public IBulkManager OrdersBulkManager
{
    get { return ObjectFactory.GetInstance<IBulkManager>(); }
}