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. lnmp升级php

    引言 服务器用的是lnmp一键安装包,但是php版本是5.5.项目用的是TP5.1需要php5.6的环境. 好慌! 进行升级操作 进入lnmp安装环境 ./upgrade.sh php 然后输入php ...

  2. Mac OS 下安装 Vagrant

    Vagrant是一款用来构建虚拟开发环境的工具,它其实算是一个跨平台的虚拟机管理工具 1 安装 1.1 安装Vagrant 下载好pkg文件后,下一步安装即可 1.2 安装Virtualbox Vag ...

  3. Vue.js 数据绑定语法详解

    Vue.js 数据绑定语法详解 一.总结 一句话总结:Vue.js 的模板是基于 DOM 实现的.这意味着所有的 Vue.js 模板都是可解析的有效的 HTML,且通过一些特殊的特性做了增强.Vue ...

  4. Rails 5 Test Prescriptions 第11章其他部分的测试。

    Routes✅ Helper Methods✅ Controllers and Requests✅ Simulating Requests⚠️,看之前的博客 What to Expect in a R ...

  5. ultraedit开发使用技巧

    抛开Mybatis和Hibernate这些dao框架,如果维护老项目时或者不得不用sql拼接时,一个几百行的sql光是去掉navicat中查询的注释或者在sql前后加上双引号就已经很费劲,影响开发效率 ...

  6. 关于CMD中延迟环境变量嵌套的实现方法

    在我昨天做的一个bat中(自动按日期重命名文件名)涉及到这方面的问题 以前涉及到这里时就想别的办法替代过去,今天好好扒出来说说: 实现变量嵌套的2种方法: 1,使用call实现变量嵌套 变量嵌套:即在 ...

  7. java的继承(编程思想)

    继承语法: extends 初始化基类: 由于现在设计基类和导出类两个类,而不是一个类,所以要试着想像导出类锁产生的结果对象,会有些困惑.从外部看来,它就像是一个与基类具有相同接口的新类,或许还会有一 ...

  8. spring boot 教程(三)配置详解

    在大部分情况下,我们不需要做太多的配置就能够让spring boot正常运行.在一些特殊的情况下,我们需要做修改一些配置,或者需要有自己的配置属性. Spring Boot 支持多种外部配置方式 这些 ...

  9. 博客网站-Hexo+GitHub+Netlify

    Hexo+GitHub+Netlify一站式搭建属于自己的博客网站 https://www.cnblogs.com/kerbside/p/10130606.html https://hhongwen. ...

  10. 6-19 Count Connected Components(20 分)

    Write a function to count the number of connected components in a given graph. Format of functions: ...