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. bzoj1143: [CTSC2008]祭祀river 最长反链

    题意:在遥远的东方,有一个神秘的民族,自称Y族.他们世代居住在水面上,奉龙王为神.每逢重大庆典, Y族都会在水面上举办盛大的祭祀活动.我们可以把Y族居住地水系看成一个由岔口和河道组成的网络.每条河道连 ...

  2. Arrays.copyof(···)与System.arraycopy(···)区别

    首先观察先System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)的声明: public stati ...

  3. Java队列的两种实现方式

    1. 基于数组 package Algorithm.learn; import java.util.Arrays; /** * Created by liujinhong on 2017/3/7. * ...

  4. 208. Implement Trie (Prefix Tree) -- 键树

    Implement a trie with insert, search, and startsWith methods. Note:You may assume that all inputs ar ...

  5. java之正则表达式的使用1

    正则表达式: 主要作用: a.匹配 b.切割 c.替换 d.获取 1.反斜杠和转义字符 废话不多说,直接上demo public static void main(String[] args) { / ...

  6. 【LeetCode 144_二叉树_遍历】Binary Tree Preorder Traversal

    解法一:非递归 vector<int> preorderTraversal(TreeNode* root) { vector<int> res; if (root == NUL ...

  7. specialized English for automation-Lesson 3 CMOS Logic Circuit

    CMOS logic is a newer technology, based on the use of complementary MOS transistors toperform logic ...

  8. promise的基础知识

    promise 相当于异步操作结果的占位符 它不会去订阅一个事件,也不会传递一个回调函数给目标函数,而是让函数返回一个promise,例如: let promise = readFile('a.txt ...

  9. w3m使用小记

    By francis_hao    Mar 8,2017   w3m是一个基于文本的web浏览器和分页器,运行在unix和windows系统上. 可显示包含链接的超文本标记语言(HTML),显示效果如 ...

  10. c/c++ socket函数详解

    c/c++ socket函数详解 注意: 使用socketAPI前,要先将相关链接库(Ws2_32.lib)加入链接,并使用WSAStartUp函数初始化.每个socket函数都可能失败(返回-1), ...