说明:本文是对参考文章的一个整理,做一个记录,基本没有翻译,详情请参看原文.

使用注意要点:

Autofac will track every disposable component instance that it creates, no matter how that instance is requested.

Don’t resolve from the root container. Always resolve from and then release a lifetime scope.

不推荐、不宜的用法:

一、

interface IMyResource { … }

class MyResource : IMyResource, IDisposable { … }

When an instance of MyResource is created in an Autofac container, the container will hold a reference to it even when it is no longer being used by the rest of the program. This means that the garbage collector will be unable to reclaim the memory held by that component, so the following program will eventually exhaust all available memory and crash
var builder = new ContainerBuilder();
builder.RegisterType<MyResource>().As<IMyResource>();
using (var container = builder.Build())
{
while (true)
var r = container.Resolve<IMyResource>(); // Out of memory!
}
his is a far cry from typical CLR behaviour, which is one more reason why it is good to get away from thinking about an IoC container as a replacement for new. If we’d just created MyResource directly in the loop, there wouldn’t be any problem at all
while (true)
var r = new MyResource(); // Fine, feed the GC

二、

interface IMyService { }

class MyComponent : IMyService
{
// Dependency on a service provided by a disposable component
public MyComponent(IMyResource resource) { … }
} If a second component is resolved that depends on a service provided by a disposable component, the memory leak still occurs
while (true)
// Still holds instances of MyResource
var s = container.Resolve<IMyService>();

三、

interface IMyService2
{
void Go();
} class MyComponent2 : IMyService2
{
Func<IMyResource> _resourceFactory; public MyComponent(Func<IMyResource> resourceFactory)
{
_resourceFactory = resourceFactory;
} public void Go()
{
while (true)
var r = _resourceFactory(); // Still out of memory.
}
}

有什么方式可以改善上面的情况呢?

答:lifetime Scopes

// var container = …
while (true)
{
using (var lifetimeScope = container.BeginLifetimeScope())
{
var r = lifetimeScope.Resolve<IMyResource>();
// r, all of its dependencies and any other components
// created indirectly will be released here
}
}

Lifetime Scopes 可以被嵌套使用:

var ls1 = container.BeginLifetimeScope();
var ls2 = ls1.BeginLifetimeScope();
// ls1 is a child of the container, ls2 is a child of ls1

Lifetime Scopes 不会产生上下文依赖:

var ls1 = container.BeginLifetimeScope();
var ls2 = container.BeginLifetimeScope();
// ls1 and ls2 are completely independent of each other

Owned Instance:

Owned instances (Owned<T>) are the last tale in Autofac’s lifetime story.

An owned instance is a component that comes wrapped in its own lifetime scope. This makes it easier to keep track of how a component should be released, especially if it is used outside of a using statement.

To get an owned instance providing service T, you can resolve one directly from the container

var ownedService = container.Resolve<Owned<IMyService>>();

In lifetime terms, this is equivalent to creating a new lifetime scope from the container, and resolving IMyService from that. The only difference is that the IMyService and the lifetime scope that holds it come wrapped up together in a single object.

The service implementation is available through the Value property:

// Value is IMyService
ownedService.Value.DoSomething();

When the owned instance is no longer needed, it and all of its disposable dependencies can be released by disposing the Owned<T> object:

ownedService.Dispose();

Owner Instance 与 Fun 结合使用:

Components that are returned from Func<T> delegates are associated with the same lifetime scope as the delegate itself. If that component is itself contained in a lifetime scope, and it creates a finite number of instances through the delegate, then there’s no problem – everything will be cleaned up when the scope completes.

If the component calling the delegate is a long-lived one, then the instances returned from the delegate will need to be cleaned up eagerly. To do this, Owned<T> can be used as the return value of a factory delegate

class MyComponent2 : IMyService2
{
Func<Owned<IMyResource>> _resourceFactory; public MyComponent(Func<Owned<IMyResource>> resourceFactory)
{
_resourceFactory = resourceFactory;
} public void Go()
{
while (true)
using (var r = _resourceFactory())
// Use r.Value before disposing it
}
} Func<T> and Owned<T> can be combined with other relationship types to define relationships with a clearer intent than just taking a dependency on ILifetimeScope

参考文章:

http://nblumhardt.com/2011/01/an-autofac-lifetime-primer/

http://nblumhardt.com/2010/01/the-relationship-zoo/

关于Autofac的使用陷阱的更多相关文章

  1. 深入理解Autofac生命周期

    为什么Autofac表现的这样? 这里似乎有几个陷阱,虽然这里只有一个------并且这个值得重申: Autofac将会跟踪每一个他所创建的可销毁的组件实例,无论这个实例是怎样被获取的. 当然,最终. ...

  2. Autofac容器对象实例的几种生命周期类型

    实例范围决定了如何在同一服务的请求之间共享实例. 请注意,您应该熟悉生命周期范围的概念,以便更好地理解此处发生的情况. 当请求服务时,Autofac可以返回单个实例(单实例作用域),新实例(每个依赖作 ...

  3. .NET手记-为ASP.NET MVC程序集成Autofac

    MVC Autofac总是会紧跟最新版本的ASP.NET MVC框架,所以文档也会一直保持更新.一般来讲,不同版本的框架集成Autofac的方法一般不变. MVC集成需要引用 Autofac.Mvc5 ...

  4. autofac生命周期入门(如何避免内存泄漏)

    如果你是一个IOC新手,那么生命周期可能会比较难以理解.以至于谈到这个问题时,一些老手也时常表示疑虑和害怕.一个令人不安的问题就是-对象没有在合适的时机被销毁.这样一来内存的使用率就会一直攀升,直到程 ...

  5. AutoFac在项目中的应用

    技能大全:http://www.cnblogs.com/dunitian/p/4822808.html#skill 完整Demo:https://github.com/dunitian/LoTCode ...

  6. Autofac - MVC/WebApi中的应用

    Autofac前面写了那么多篇, 其实就是为了今天这一篇, Autofac在MVC和WebApi中的应用. 一.目录结构 先看一下我的目录结构吧, 搭了个非常简单的架构, IOC(web), IBLL ...

  7. Autofac - 生命周期

    实例生命周期决定在同一个服务的每个请求的实例是如何共享的. 当请求一个服务的时候,Autofac会返回一个单例 (single instance作用域), 一个新的对象 (per lifetime作用 ...

  8. Autofac - 属性注入

    属性注入不同于通过构造函数方式传入参数. 这里是通过注入的方式, 在类创建完毕之后, 资源释放之前, 给属性赋值. 这里, 我重新弄一些类来演示这一篇吧. public class ClassA { ...

  9. Autofac 的点滴

    泛型类型的注册和使用 public interface IRepository<T> where T:class { } public interface ISchoolDetailRep ...

随机推荐

  1. java多线程之 Executors线程池管理

    1. 类 Executors 此类中提供的一些方法有: 1.1 public static ExecutorService newCachedThreadPool() 创建一个可根据需要创建新线程的线 ...

  2. 《Java数据结构与算法》笔记-CH4-4循环队列

    /** * 循环队列 */ class Queue { private int maxSize; private long[] queue; private int front; private in ...

  3. HDU-2888 Check Corners 二维RMQ

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2888 模板题.解题思路如下(转载别人写的): dp[row][col][i][j] 表示[row,ro ...

  4. 利用AuthorizeAttribute属性简单避免 MVC 中的跨域攻击

    跨域攻击---自然来路页面和目标页面不在同一个域下,所以直接判断来路域和当前自己的域就可以了. 可以广泛应用于表单提交,ajax调用或者某些不想让用户直接输入网址看到的页面 [csharp] view ...

  5. 第二百一十九天 how can I 坚持

    今天好冷,白天在家待了一天,晚上,老贾生日,生日快乐,去海底捞吃了个火锅,没感觉呢. 今天还发现了个好游戏,纪念碑谷,挺新颖,就是难度有点大了. 好累.睡觉,明天想去爬山啊,可是该死的天气.

  6. SCP和SFTP(转)

    原文:http://www.cnblogs.com/wang_yb/p/3819441.html 不管SCP还是SFTP,都是SSH的功能之一.都是使用SSH协议来传输文件的. 不用说文件内容,就是登 ...

  7. HDU 5858 Hard problem (数学推导)

    Hard problem 题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5858 Description cjj is fun with ...

  8. Labview中的属性节点

    获取(读取)和/或设置(写入)引用的属性.通过属性节点对本地或远程应用程序实例.VI或对象获取或设置属性和方法也可通过属性节点访问LabVIEW类的私有数据. 属性节点可自动调整为用户所引用的对象的类 ...

  9. [置顶] 如何在浏览器中打开PDF文件并实现预览的思路与代码

    编写项目遇到一个需要在浏览器中打开PDF文件的问题.最终实现效果如下: 其实也就是简单的在浏览器中实现一个打开pdf文件,并有类似预览功能的边框. 其实在网上经常见到类似的页面,在浏览器中打开pdf文 ...

  10. C# JSON使用的常用技巧(一)

    获取JSON无格式的字符串: new JArray().ToString(Newtonsoft.Json.Formatting.None): 如: {"A":123,"B ...