Having said that, here is a solution that you can use with the Unity container:

Create some custom attributes for the different lifetime styles that you want to have like this:

[AttributeUsage(AttributeTargets.Class)]
public class SingletonAttribute : Attribute
{ } [AttributeUsage(AttributeTargets.Class)]
public class TransientAttribute : Attribute
{ }

You can have these attributes in some common library and reference it from your service class libraries.

Then, apply these attributes to your service classes in your class libraries like in your question:

[Singleton]
public class ServiceImplA : IService
{} [Transient]
public class ServiceImplB : IService
{}

Now, define a helper method that can get the lifetime manager based on reflection like this:

public static LifetimeManager GetLifeTimeManager<T>()
{
Type type = typeof (T); if(type.GetCustomAttribute(typeof(TransientAttribute)) != null)
return new TransientLifetimeManager(); if (type.GetCustomAttribute(typeof(SingletonAttribute)) != null)
return new ContainerControlledLifetimeManager(); //Add more cases here return new TransientLifetimeManager(); //Default is transient
}

And use it like this:

container.RegisterType<IService, ServiceImplA>(GetLifeTimeManager<ServiceImplA>());

By the way, this solution is DI container independent. I mean that the attributes themselves are not specific to any container. It is the GetLifeTimeManager helper method that is specific to the Unity container. But you can use other DI containers and define similar helper methods for them.

You can also create extension methods to hide the invocation of the helper method like this:

public static IUnityContainer RegisterTypeWithLifeTime<TFrom, TTo>(this IUnityContainer container) where TTo : TFrom
{
return container.RegisterType<TFrom, TTo>(GetLifeTimeManager<TTo>());
}

And use it like this:

container.RegisterTypeWithLifeTime<IService, ServiceImplA>();

You just need to constrain the types returned to types that are annotated with the Singletonattribute:

container.RegisterTypes(
AllClasses.FromLoadedAssemblies()
.Where(t => t.GetCustomAttributes<SingletonAttribute>(true).Any()),
WithMappings.FromMatchingInterface,
WithName.Default,
WithLifetime.ContainerControlled);

You could register everything and then overwrite the registration for any singletons with a ContainerControlledLifetimeManager:

// Register All Types by Convention by default
container.RegisterTypes(
AllClasses.FromLoadedAssemblies(),
WithMappings.FromMatchingInterface,
WithName.Default,
WithLifetime.Transient); // Overwrite All Types marked as Singleton
container.RegisterTypes(
AllClasses.FromLoadedAssemblies()
.Where(t => t.GetCustomAttributes<SingletonAttribute>(true).Any()),
WithMappings.FromMatchingInterface,
WithName.Default,
WithLifetime.ContainerControlled,
null,
true); // Overwrite existing mappings without throwing

Another Container:

using System;
using System.Reflection;
using SimpleInjector.Advanced; // Attribute for use by the application
public enum CreationPolicy { Transient, Scoped, Singleton } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface,
Inherited = false, AllowMultiple = false)]
public sealed class CreationPolicyAttribute : Attribute {
public CreationPolicyAttribute(CreationPolicy policy) {
this.Policy = policy;
} public CreationPolicy Policy { get; private set; }
} // Custom lifestyle selection behavior
public class AttributeBasedLifestyleSelectionBehavior : ILifestyleSelectionBehavior {
private const CreationPolicy DefaultPolicy = CreationPolicy.Transient; public Lifestyle SelectLifestyle(Type serviceType, Type implementationType) {
var attribute = implementationType.GetCustomAttribute<CreationPolicyAttribute>()
?? serviceType.GetCustomAttribute<CreationPolicyAttribute>(); switch (attribute != null ? attribute.Policy : DefaultPolicy) {
case CreationPolicy.Singleton: return Lifestyle.Singleton;
case CreationPolicy.Scoped: return Lifestyle.Scoped;
default: return Lifestyle.Transient;
}
}
} // Usage
var container = new Container();
container.Options.DefaultScopedLifestyle = new WebRequestLifestyle(); container.Options.LifestyleSelectionBehavior =
new AttributeBasedLifestyleSelectionBehavior(); container.Register<IUserContext, AspNetUserContext>(); // Usage in application
[CreationPolicy(CreationPolicy.Scoped)]
public class AspNetUserContext : IUserContext {
// etc
}

Unity容器声明周期管理的更多相关文章

  1. 004-docker命令-容器生命周期管理、容器操作

    1.容器生命周期管理 docker run :创建一个新的容器并运行一个命令 语法:docker run [OPTIONS] IMAGE [COMMAND] [ARG...] OPTIONS说明: - ...

  2. Salesforce LWC学习(四) 父子component交互 / component声明周期管理 / 事件处理

    我们在上篇介绍了 @track / @api的区别.在父子 component中,针对api类型的变量,如果声明以后就只允许在parent修改,son component修改便会导致报错. sonIt ...

  3. 044、vloume声明周期管理(2019-03-07 周四)

    参考https://www.cnblogs.com/CloudMan6/p/7214828.html   如果Data Volume 中存放的是重要的应用数据,如何管理volume对应用至关重要.   ...

  4. Docker系列02: 容器生命周期管理 镜像&容器

    A) Docker信息1. 查看docker运行状态 systemctl status docker docker.service - Docker Application Container Eng ...

  5. Docker 容器生命周期管理命令

    docker run 命令 -d: 后台运行容器,并返回容器ID: -i: 以交互模式运行容器,通常与 -t 同时使用: -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用: --name= ...

  6. rxjava封装,RxBus封装(上线项目集成,声明周期管理,处理溢出内存,支持同时多个请求。)

    Github地址 RxLibrary工程:1.rxjava2 + retrofit2的封装,常用的请求(Get,Post,文件上传,文件下载),防止内存泄漏,简单便捷,支持自定义loading等属性. ...

  7. Docker容器与镜像管理

    目录 容器管理 运行容器 容器的启停操作 容器导入导出 容器生命周期管理 容器资源限制 内存限制 CPU限制 io 限制 镜像管理 镜像命名规范 镜像基本操作 容器管理 运行容器 1.运行一个容器示例 ...

  8. Castle IOC容器组件生命周期管理

    主要内容 1.生命处理方式 2.自定义生命处理方式 3.生命周期处理 一.生命处理方式 我们通常创建一个组件的实例使用new关键字,这样每次创建出来的都是一个新的实例,如果想要组件只有一个实例,我们会 ...

  9. [原创]java WEB学习笔记31:会话与状态管理 session机制 概述(定义,session机制,session的声明周期,保存session的方式,Session的创建与删除)

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

随机推荐

  1. JavaScript里Math对象的ceil()、floor()、round()方法的区别

    ceil(x) 官方含义:对一个数进行上舍入.理解:ceiling为天花板的意思,意译为向上取整.即取得大于于等于x的最大整数. floor(x) 官方含义:对一个数进行下舍入.理解:floor为地板 ...

  2. 使用 Rcpp

    正如我们所提到的那样,并行计算只有在每次迭代都是独立的情况下才可行,这样最终结果才不会依赖运行顺序.然而,并非所有任务都像这样理想.因此,并行计算可能会受到影响.那么怎样才能使算法快速运行,并且可以轻 ...

  3. 【Python】xlrd,NotImplementedError-formatting_info=True not yet implemented

    前言 Python需要读取Excel(.xls..xlsx)时通常使用xlrd模块:如果要对其内容进行编辑的话稍稍有些麻烦,通常的做法是使用xlutils的copy模块对原文件进行复制,然后保存成新的 ...

  4. 【源码学习之spark core 1.6.1 standalone模式下的作业提交】

    说明:个人原创,转载请说明出处 http://www.cnblogs.com/piaolingzxh/p/5656876.html 未完待续

  5. 【转】Scala基础知识

    原文地址.续 课程内容: 关于这节课 表达式 值 函数 类 继承 特质 类型 apply方法 单例对象 函数即对象 包 模式匹配 样本类 try-catch-finally 关于这节课 最初的几个星期 ...

  6. HDU1754 I hate it_线段树(入门级别)

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  7. sqlserver版本分类下载以及各个版本之间的区别是什么

    很多用visual studio做开发的朋友经常会用到sqlserver数据库,但是往往在选择的时候就不知道该使用哪个版本了,今天亦是美网络就给大家分享一下sqlserver各个版本之间的区别,以及各 ...

  8. 纪念又一次ak

    t1网络流 随便建个图就可以了 t2单调队列 分成两组来做 t3dp+高精度 为了不被卡厂用了万进制

  9. 【Ubuntu14】Nginx+PHP5+Mysql记录

    这次因为工作原因,需要在Linux下进行开发.推荐的环境是Ubuntu14+Nginx+PHP+Mysql.环境搭建好之后,装上GIT,装上IDE,觉得Mysql命令界面麻烦又装了个Navicat.总 ...

  10. [Tomcat无法启动]'Starting Tomcat v8.0 Server at localhost' has encountered a problem.

    运行一个index.jsp,运行提示如下错误:点击服务器 解决办法1: 点击Tomcat服务器,将服务器里的web工程删除掉,再重新运行index.jsp. 解决办法2: 关闭Tomcat,最简单的方 ...