castle windsor学习----- Lifestyles

1.Singleton 单例

2.Transient 瞬态

3.PerWebRequest 每一次web请求

  当请求开始时组件会被创建,请求结束时释放

   1)PerWebRequestLifestyleModule

  

<httpModules>
   <add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor"/>
</httpModules>

IIS7配置

<configuration>
   <system.webServer>
      <modules>
         <add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" />
      </modules>
   </system.webServer>
</configuration>

4.Scoped 作用域 

Container.Register(Component.For<MyScopedComponent>().LifestyleScoped());
using Castle.MicroKernel.Lifestyle;

using (Container.BeginScope()) //extension method
{
    var one = Container.Resolve<MyScopedComponent>();
    var two = Container.Resolve<MyScopedComponent>();
    Assert.AreSame(one, two);

} // releases the instance

 

 用户自定义作用域

Container.Register(Component.For<MyScopedComponent>().LifestyleScoped<MyCustomScopeAccessor>());

 

需要实现如下接口

public interface IScopeAccessor : IDisposable
{
    ILifetimeScope GetScope(CreationContext context);
}

 

例子:

如果你建立一个B2B应用程序,每个客户公司有自己的一个生命周期,你可以定义如下

 

public class PerClientCompanyScopeAccessor : IScopeAccessor
{
    private static readonly ConcurrentDictionary<Guid, ILifetimeScope> collection = new ConcurrentDictionary<Guid, ILifetimeScope>();

    public ILifetimeScope GetScope(Castle.MicroKernel.Context.CreationContext context)
    {
        var companyID = ClientHelper.GetCurrentClientCompanyId();
        return collection.GetOrAdd(companyID, id => new ThreadSafeDefaultLifetimeScope());
    }

    public void Dispose()
    {
        foreach (var scope in collection)
        {
            scope.Value.Dispose();
        }
        collection.Clear();
    }
}
public class ThreadSafeDefaultLifetimeScope : ILifetimeScope
{
    private static readonly Action<Burden> emptyOnAfterCreated = delegate { };
    private readonly object @lock = new object();
    private readonly Action<Burden> onAfterCreated;
    private IScopeCache scopeCache;

    public ThreadSafeDefaultLifetimeScope(IScopeCache scopeCache = null, Action<Burden> onAfterCreated = null)
    {
        this.scopeCache = scopeCache ?? new ScopeCache();
        this.onAfterCreated = onAfterCreated ?? emptyOnAfterCreated;
    }

    public void Dispose()
    {
        lock (@lock)
        {
            if (scopeCache == null)
            {
                return;
            }
            var disposableCache = scopeCache as IDisposable;
            if (disposableCache != null)
            {
                disposableCache.Dispose();
            }
            scopeCache = null;
        }
    }

    public Burden GetCachedInstance(ComponentModel model, ScopedInstanceActivationCallback createInstance)
    {
        lock (@lock)
        {
            var burden = scopeCache[model];
            if (burden == null)
            {
                scopeCache[model] = burden = createInstance(onAfterCreated);
            }
            return burden;
        }
    }
}

 

Bound

Somewhere in the graph we have two view models, one depending on the other, and both of them depend on some other service, say a repository. You might want to bind the repository to the subgraph. In other words you might want the entire subgraph of the outermost view model (WelcomeScreenViewModel) to share the same instance of the repository, and to have the repository released when the view model itself is released.

This is what bound lifestyle is for.

Container.Register(Component.For<Repository>().LifestyleBoundTo<ViewModelBase>());

 

posted @ 2017-03-11 11:28  蓝平凡  阅读(593)  评论(0编辑  收藏  举报