关于国际奥委会的问题

发布于 2024-11-14 21:26:24 字数 420 浏览 1 评论 0原文

我已经依赖 IoC 模式一年了,现在使用结构图和结构图。 ASP.NET MVC。 IoC 真的很简洁,特别是如果你的类中有很多依赖项,只需在构造函数中注入依赖项,然后完成,IoC 就会自动为你注入它。

我的问题是,我将 asp.net mvc 与具有 IServices 依赖项的控制器类一起使用。

我仅需要某个控制器操作的依赖服务,比如“/customer/add” 但我不需要对其他操作的依赖,比如“/Customer/Index”。但是,由于我在构造函数中使用 DI(依赖项注入),因此即使我不需要它们,依赖项也始终会被实例化。这有什么好处吗?对象创建非常昂贵并且消耗内存占用。

当然,我可以在操作中执行container.GetInstance,但这不是一个好的做法,因为您将在代码和单元测试中严重依赖IoC。

有什么建议吗?如果我做错了什么请纠正我。

I've been relying on IoC pattern for 1 year now using structuremap & asp.net mvc. IoC is really neat especially if you have a lot of dependencies in your class, just inject dependency in your constructor and your done, the IoC will auto-inject it for you.

My question is that im using asp.net mvc with a controller class which have IServices dependencies.

I need the dependency services only for a certain controller action let say "/customer/add"
but i don't need those dependency on other action let say "/Customer/Index". However, since i'm using a DI (Dependency injection) in constructor, the dependency are always instantiated even if i don't need them. Is that any good? object creation is expensive and consume memory footprint.

Of course, i can do container.GetInstance inside an action, but it is not a good practice since you will heavily be dependent on IoC in your code and unit testing.

Any suggestion? correct me if im wrong with something.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

月亮坠入山谷 2024-11-21 21:26:24

针对 jgauffins 评论进行了更新

我发现有两种简单的方法可以解决您的问题:

将服务工厂注入您的构造函数并按需创建服务。

interface IFooService
{
    void Bar();
}

interface IFooServiceFactory
{
    IFooService CreateFooService();
}

class YourController
{
    public YourController(IFooServiceFactory fooServiceFactory)
    {
        this.fooServiceFactory = fooServiceFactory;
    }

    public void YourAction()
    {
        IFooService fooService = this.fooServiceFactory.CreateFooService();
        fooService.Bar();
    }
}

将服务代理注入到您的构造函数中,并让代理按需创建真正的服务。

interface IFooService
{
    void Bar();
}

class FooServiceProxy : IFooService
{
    private IFooService realFooService;


    void IFooService.Bar()
    {
         IFooService realFooService = GetRealFooService();
         realFooService.Bar();
    }

    private IFooService GetRealFooService()
    {
        if(this.realFooService == null)
        {
            this.realFooService = CreateRealFooService();
        }
        return this.realFooService;
    }

    private IFooService CreateRealFooService()
    {
        // You could inject the service factory in the constructor of the proxy and use it here to create the real service.
    }
}

class YourController
{

                          Inject FooServiceProxy here
                          v
                          v 
    public YourController(IFooService fooService)
    {
         this.fooService = fooService;
    }

    public void YourAction()
    {
         this.fooService.Bar();
    }
}

Updated in response to jgauffins comment

I see two straightforward ways to solve your issue:

Inject a service factory to your constructor and create the service on demand.

interface IFooService
{
    void Bar();
}

interface IFooServiceFactory
{
    IFooService CreateFooService();
}

class YourController
{
    public YourController(IFooServiceFactory fooServiceFactory)
    {
        this.fooServiceFactory = fooServiceFactory;
    }

    public void YourAction()
    {
        IFooService fooService = this.fooServiceFactory.CreateFooService();
        fooService.Bar();
    }
}

Inject a service proxy to your constructor and let the proxy create the real service on demand.

interface IFooService
{
    void Bar();
}

class FooServiceProxy : IFooService
{
    private IFooService realFooService;


    void IFooService.Bar()
    {
         IFooService realFooService = GetRealFooService();
         realFooService.Bar();
    }

    private IFooService GetRealFooService()
    {
        if(this.realFooService == null)
        {
            this.realFooService = CreateRealFooService();
        }
        return this.realFooService;
    }

    private IFooService CreateRealFooService()
    {
        // You could inject the service factory in the constructor of the proxy and use it here to create the real service.
    }
}

class YourController
{

                          Inject FooServiceProxy here
                          v
                          v 
    public YourController(IFooService fooService)
    {
         this.fooService = fooService;
    }

    public void YourAction()
    {
         this.fooService.Bar();
    }
}
咽泪装欢 2024-11-21 21:26:24

我总是使用构造函数。恕我直言,属性只能用于解决循环依赖。

原因是使用属性时意图不明确。如果未设置属性 MyController.MyProperty ,代码中没有任何内容表明 MyController.DoThat 将无法工作。

如果一个方法需要特定的服务,那么整个类都需要该服务。否则你就会违反你的班级公开的合同。

I always use constructors. imho properties should only be used to solve circular dependencies.

The reason is that the intent is not clear when using properties. Nothing in your code says that MyController.DoThat wont work if the property MyController.MyProperty is not set.

If a method needs a specific service, then the service is required for your whole class. Else you'll break the contract that your class exposes.

眉黛浅 2024-11-21 21:26:24

<块引用>

即使我不需要它们,依赖关系也总是被实例化。这样有好处吗?

尽管并非类的每个部分都需要依赖项,但类本身需要该依赖项,因此它不是可选依赖项。通常,当您发现类的一部分使用某些依赖项而另一部分使用其他依赖项时,您的类可能违反了 建议零售价;它可能正在做不止一件事。然而,将它们分开可能不会对您有帮助,因为 MVC Controller 类更关注接口,所以我将保持原样。

<块引用>

对象创建成本高昂且消耗内存。

引用类型总是有 8 个字节的开销(在 32 位平台上),所以这并不多。通常注入的服务对象包含很少的状态,通常只是一些配置值和对其依赖项的引用。从内存的角度来看,与流经应用程序的数据(例如数据库中的数据或 MVC 生成的用于构建 HTML 的字符串)相比,它毫无意义。它确实取决于您使用的 DI 框架,但通常即使是相对较大的依赖关系图也会在瞬间生成。即使图构建花费太多时间,也有其他方法来优化性能。例如,考虑使用单例生活方式定义一些服务。如果这还不够,您可能需要考虑切换到更快的 DI 框架。然而,StructureMap 是该领域更快 DI 容器之一(较常见的容器),因此对于正常的应用程序开发,这应该不成问题。

the dependency are always instantiated even if i don't need them. Is that any good?

Although not every part of the class requires the dependency, the class itself needs that dependency and it is therefore not an optional dependency. Typically when you see that some dependencies are used in one part of the class and other dependency in another part, your class might be violating the SRP; it might be doing more than one thing. Splitting them up however, would probably not help you since MVC Controller classes are more focused around interfaces, so I would just leave it as it is.

object creation is expensive and consume memory footprint.

Reference types always have a 8 bytes overhead (on the 32 bits platform), so that's not much. The service object you would normally inject do contain very little state, often just some configuration values and references to their dependencies. From a memory perspective, it is nothing compared to the data that flows through you application (such as data from the database or the strings that get generated by MVC to build the HTML). It does depend on the DI framework you use, but typically even a relatively big dependency graph will get generated in a split second. And even when graph construction takes too much time, there are other ways to optimize performance. Consider defining some services with a singleton lifestyle for instance. When this is not enough, you might want to consider switching to a faster DI framework. StructureMap however, is one of the faster DI containers in the field (of the more commonly known ones), so for normal application development, this shouldn't be a problem.

箹锭⒈辈孓 2024-11-21 21:26:24

我一直这样做的方式是,对于可选注入的依赖项(例如在您刚刚描述的场景中,只有某些方法需要依赖项),将它们设置为属性< /强>。对于必需依赖项,请使用构造函数注入。

The way I've always done it was that for injected dependencies that are optional (such as in the scenario you just described where only certain methods requires the dependency), set them up as properties. For required dependencies, use constructor injection.

最后的乘客 2024-11-21 21:26:24

StructureMap 支持延迟实例化 - 无需构建自己的服务工厂/代理解决方案。如果您只想在使用 IService 的操作中实例化它,请将 Func 注入您的构造函数。然后,在需要它的操作中,调用 Func 以返回实例。

class CustomerController {
  Func<IService> _service;

  public CustomerController(Func<IService> service){
    _service = service;
  }

  public ActionResult Index(){
    _service().CallMethodOnService();
  }
}

然而,在进行这项额外的工作之前,我首先要确保实例化服务确实是一个性能问题。

StructureMap supports delayed instantiation - no need to craft your own service factory/proxy solution. If you only want IService instantiated when in the actions it is used, inject a Func<IService> into your constructor instead. Then, in your action that needs it, invoke the Func to return the instance.

class CustomerController {
  Func<IService> _service;

  public CustomerController(Func<IService> service){
    _service = service;
  }

  public ActionResult Index(){
    _service().CallMethodOnService();
  }
}

However, I would first make sure that instantiating the service really is a performance problem before going to this extra effort.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文