.net core2.0下Ioc容器Autofac使用

Autofac基本使用

  Autofac是一款轻量级的IOC框架,使用率上还是挺高的,官方网站http://autofac.org,源码下载地址https://github.com/autofac/Autofac。

  下面以狗的列子来介绍autofac,nuget搜索Autofac进行安装

public interface IDog

    {

        /// <summary>

        /// 品种

        /// </summary>

        string Breed { get; }


        /// <summary>

        /// 名称

        /// </summary>

        string Name { get; }

    }


    /// <summary>

    /// 萨摩耶

    /// </summary>

    public class Samoyed : IDog

    {

        /// <summary>

        /// 品种

        /// </summary>

        public string Breed

        {

            get

            {

                return "Samoyed(萨摩耶)";

            }

        }


        /// <summary>

        /// 名称

        /// </summary>

        public string Name

        {

            get

            {

                return "小黄";

            }

        }

    }


    /// <summary>

    /// 藏獒

    /// </summary>

    public class TibetanMastiff : IDog

    {

        /// <summary>

        /// 品种

        /// </summary>

        public string Breed

        {

            get

            {

                return "Mastiff Class(獒犬类)";

            }

        }


        /// <summary>

        /// 名称

        /// </summary>

        public string Name

        {

            get

            {

                return "小黑";

            }

        }

    }

1.RegisterType 

public static void Register()

{

    var builder = new ContainerBuilder();

    //注册Samoyed指定为IDog实现

    builder.RegisterType<Samoyed>().As<IDog>();

    builder.RegisterType<TibetanMastiff>().As<IDog>();

    using (var container = builder.Build())

    {

        var dogs = container.Resolve<IEnumerable<IDog>>();

        foreach (var dog in dogs)

        {

             Console.WriteLine($"名称:{dog.Name},品种:{dog.Breed}");

        }

    }

}


2.RegisterAssemblyTypes

public static void RegisterAssemblyTypes()

{

    var builder = new ContainerBuilder();

    //注册程序集下所有类型

    builder.RegisterAssemblyTypes(typeof(Program).Assembly).AsImplementedInterfaces();

    using (var container = builder.Build())

    {

        var dogs = container.Resolve<IEnumerable<IDog>>();

        foreach (var dog in dogs)

        {

            Console.WriteLine($"名称:{dog.Name},品种:{dog.Breed}");

        }

    }

}

直接注册程序集下的所有类型,AsImplementedInterfaces(让具体实现类型,可以该类型继承的所有接口类型找到该实现类型)

  3.RegisterInstance

TibetanMastiff d = new TibetanMastiff();
builder.RegisterInstance(d).As<IDog>();

  4.RegisterModule

  这种模式需要使用配置文件进行注册,个人更喜欢代码直接注册的方式,毕竟配置文件修改容易遗忘和出错。这里就不介绍该方式了。 

      

  遗留问题:上面的注册代码,自己写写demo的时候没啥问题。但是运用到项目里面就很繁琐了,需要自己一个个类型注册,后面会提供解决方案。

 

.net core MVC与Autofac

  1.首先nuget下载AutofacAutofac.Extensions.DependencyInjection引用

  2.替换mvc自带的DI框架

  将Startup.cs中的ConfigureServices返回类型改为IServiceProvider

public IServiceProvider ConfigureServices(IServiceCollection services)

{

    services.AddMvc();


    var builder = new ContainerBuilder();

    builder.Populate(services);

    builder.RegisterAssemblyTypes(typeof(Startup).Assembly).AsImplementedInterfaces();

    var Container = builder.Build();

    return new AutofacServiceProvider(Container);

}

属性注入

Autofac默认是构造函数注入

[Route("api/[controller]")]

public class ValuesController : Controller

{

    private readonly IEnumerable<IDog> dogs;


    public ValuesController(IEnumerable<IDog> _dogs)

    {

        dogs = _dogs;

    }


    // GET api/values

    [HttpGet]

    public IEnumerable<string> Get()

    {

        List<string> list = new List<string>();

        foreach (var dog in dogs)

        {

            list.Add($"名称:{dog.Name},品种:{dog.Breed}");

        }

        return list.ToArray(); ;

    }

}


 

使用过mef的可能更喜欢属性注入的方式,那么使用autofac怎么实现属性注入呢?

1.注册系统所有Controller,由Autofac创建

var IControllerType = typeof(ControllerBase);
builder.RegisterAssemblyTypes(assembly).Where(t => IControllerType.IsAssignableFrom(t) && t != IControllerType).PropertiesAutowired();

 上面这段代码的解释:注册所有程序集下继承ControllerBase的类型,PropertiesAutowired 允许属性注入。

2.替换系统默认Controller创建器

services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());services.AddMvc();

注意:Replace代码放在AddMvc之前

Replace代码的意思:使用ServiceBasedControllerActivator替换DefaultControllerActivator(意味着框架现在会尝试从IServiceProvider中解析控制器实例,也就是return new AutofacServiceProvider(Container);

3.使用属性注入

[Route("api/[controller]")]

    public class ValuesController : Controller

    {

        public IEnumerable<IDog> dogs { get; set; }

        [HttpGet]

        public IEnumerable<string> Get()

        {

            List<string> list = new List<string>();

            foreach (var dog in dogs)

            {

                list.Add($"名称:{dog.Name},品种:{dog.Breed}");

            }

            return list.ToArray(); ;

        }

    }

至此完成了使用Autofac实现属性注入

Autofac+Castle实现AOP

1.首先nuget下载Autofac.Extras.DynamicProxy引用

2.编写拦截器


public class LogInterceptor : IInterceptor

{

    public void Intercept(IInvocation invocation)

    {

        Console.WriteLine("你正在调用方法 \"{0}\"  参数是 {1}... ",

           invocation.Method.Name,

           string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray()));


        invocation.Proceed();

        if (invocation.ReturnValue != null && invocation.ReturnValue is string)

        {

            //在返回接口上拼上LogInterceptor

            invocation.ReturnValue += " LogInterceptor";

        }

        Console.WriteLine("方法执行完毕,返回结果:{0}", invocation.ReturnValue);


        Console.WriteLine("开始记录日志....");

    }

}

3.开启拦截(接口拦截器  类拦截器

builder.RegisterType<LogInterceptor>();

builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces()

    .EnableInterfaceInterceptors();

var IControllerType = typeof(ControllerBase);

builder.RegisterAssemblyTypes(assembly).Where(t => IControllerType.IsAssignableFrom(t) && t != IControllerType).PropertiesAutowired()

    .EnableClassInterceptors();

var Container = builder.Build();

开启接口拦截器:EnableInterfaceInterceptors  开启类拦截器:EnableClassInterceptors
[Intercept(typeof(LogInterceptor))]
[Route("api/[controller]")]public class ValuesController : Controller
{
}
[Intercept(typeof(LogInterceptor))]public class Samoyed : IDog
{
}

这种使用方式需要自己指定在哪个类上使用,还有一种全局拦截器

builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces().EnableInterfaceInterceptors()
   .InterceptedBy(
typeof(LogInterceptor));

 


代码封装简单使用

先列出使用过程中遇到的几个问题,然后再给出解决方案

1:如何简单注册代码里面的所有类型

2.如何注册单例和普通对象

3.封装好的代码怎么支持用户特殊化注册需求

为了解决上述问题,这里给出了几个约束

单例对象需继承的接口:ISingletonDependency  普通对象需继承的接口:ITransientDependency 特殊化注册接口:IDependencyRegistrar

通过这几个约束,在初始化时找所有程序集 继承ISingletonDependency ,ITransientDependency 接口的对象进行类型注册

/// <summary>/// 单例接口    /// </summary>public interface ISingletonDependency{}

/// <summary>

    /// 所有接口的依赖接口,每次创建新实例

    /// </summary>

    /// <remarks>

    /// 用于Autofac自动注册时,查找所有依赖该接口的实现。

    /// 实现自动注册功能

    /// </remarks>

    public interface ITransientDependency

    {

    }

/// <summary>

    /// 依赖注册接口

    /// </summary>

    public interface IDependencyRegistrar

    {

        /// <summary>

        /// Register services and interfaces

        /// </summary>

        /// <param name="builder">Container builder</param>

        /// <param name="config">Config</param>

        void Register(ContainerBuilder builder,List<Type> listType);


        /// <summary>

        /// Order of this dependency registrar implementation

        /// </summary>

        int Order { get; }

    }

public interface IIocManager

    {

        IContainer Container { get; }


        bool IsRegistered(Type serviceType, ILifetimeScope scope = null);

        object Resolve(Type type, ILifetimeScope scope = null);

        T Resolve<T>(string key = "", ILifetimeScope scope = null) where T : class;

        T Resolve<T>(params Parameter[] parameters) where T : class;

        T[] ResolveAll<T>(string key = "", ILifetimeScope scope = null);

        object ResolveOptional(Type serviceType, ILifetimeScope scope = null);

        object ResolveUnregistered(Type type, ILifetimeScope scope = null);

        T ResolveUnregistered<T>(ILifetimeScope scope = null) where T : class;

        ILifetimeScope Scope();

        bool TryResolve(Type serviceType, ILifetimeScope scope, out object instance);

    }

/// <summary>

    /// Container manager

    /// </summary>

    public class IocManager : IIocManager

    {

        private IContainer _container;


        public static IocManager Instance { get { return SingletonInstance; } }

        private static readonly IocManager SingletonInstance = new IocManager();


        /// <summary>

        /// Ioc容器初始化

        /// </summary>

        /// <param name="config"></param>

        /// <returns></returns>

        public IServiceProvider Initialize(IServiceCollection services)

        {

            var builder = new ContainerBuilder();

            builder.RegisterInstance(Instance).As<IIocManager>().SingleInstance();

            //所有程序集 和程序集下类型

            var deps = DependencyContext.Default;

            var libs = deps.CompileLibraries.Where(lib => !lib.Serviceable && lib.Type != "package");//排除所有的系统程序集、Nuget下载包

            var listAllType = new List<Type>();

            foreach (var lib in libs)

            {

                try

                {

                    var assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(lib.Name));

                    listAllType.AddRange(assembly.GetTypes().Where(type => type != null));

                }

                catch { }

            }

            //找到所有外部IDependencyRegistrar实现,调用注册

            var registrarType = typeof(IDependencyRegistrar);

            var arrRegistrarType = listAllType.Where(t => registrarType.IsAssignableFrom(t) && t != registrarType).ToArray();

            var listRegistrarInstances = new List<IDependencyRegistrar>();

            foreach (var drType in arrRegistrarType)

            {

                listRegistrarInstances.Add((IDependencyRegistrar)Activator.CreateInstance(drType));

            }

            //排序

            listRegistrarInstances = listRegistrarInstances.OrderBy(t => t.Order).ToList();

            foreach (var dependencyRegistrar in listRegistrarInstances)

            {

                dependencyRegistrar.Register(builder, listAllType);

            }


            //注册ITransientDependency实现类

            var dependencyType = typeof(ITransientDependency);

            var arrDependencyType = listAllType.Where(t => dependencyType.IsAssignableFrom(t) && t != dependencyType).ToArray();

            builder.RegisterTypes(arrDependencyType)

                .AsImplementedInterfaces()

                .InstancePerLifetimeScope()

                .PropertiesAutowired().EnableInterfaceInterceptors();


            foreach (Type type in arrDependencyType)

            {

                if (type.IsClass && !type.IsAbstract && !type.BaseType.IsInterface && type.BaseType != typeof(object))

                {

                    builder.RegisterType(type).As(type.BaseType)

                        .InstancePerLifetimeScope()

                        .PropertiesAutowired();

                }

            }



            //注册ISingletonDependency实现类

            var singletonDependencyType = typeof(ISingletonDependency);

            var arrSingletonDependencyType = listAllType.Where(t => singletonDependencyType.IsAssignableFrom(t) && t != singletonDependencyType).ToArray();

            builder.RegisterTypes(arrSingletonDependencyType)

                .AsImplementedInterfaces()

                .SingleInstance()

                .PropertiesAutowired();


            foreach (Type type in arrSingletonDependencyType)

            {

                if (type.IsClass && !type.IsAbstract && !type.BaseType.IsInterface && type.BaseType != typeof(object))

                {

                    builder.RegisterType(type).As(type.BaseType)

                        .SingleInstance()

                        .PropertiesAutowired();

                }

            }


            builder.Populate(services);

            _container = builder.Build();

            return new AutofacServiceProvider(_container);

        }


        /// <summary>

        /// Gets a container

        /// </summary>

        public virtual IContainer Container

        {

            get

            {

                return _container;

            }

        }


        /// <summary>

        /// Resolve

        /// </summary>

        /// <typeparam name="T">Type</typeparam>

        /// <param name="key">key</param>

        /// <param name="scope">Scope; pass null to automatically resolve the current scope</param>

        /// <returns>Resolved service</returns>

        public virtual T Resolve<T>(string key = "", ILifetimeScope scope = null) where T : class

        {

            if (scope == null)

            {

                //no scope specified

                scope = Scope();

            }

            if (string.IsNullOrEmpty(key))

            {

                return scope.Resolve<T>();

            }

            return scope.ResolveKeyed<T>(key);

        }


        /// <summary>

        /// Resolve

        /// </summary>

        /// <typeparam name="T">Type</typeparam>

        /// <param name="key">key</param>

        /// <param name="scope">Scope; pass null to automatically resolve the current scope</param>

        /// <returns>Resolved service</returns>

        public virtual T Resolve<T>(params Parameter[] parameters) where T : class

        {

            var scope = Scope();

            return scope.Resolve<T>(parameters);

        }


        /// <summary>

        /// Resolve

        /// </summary>

        /// <param name="type">Type</param>

        /// <param name="scope">Scope; pass null to automatically resolve the current scope</param>

        /// <returns>Resolved service</returns>

        public virtual object Resolve(Type type, ILifetimeScope scope = null)

        {

            if (scope == null)

            {

                //no scope specified

                scope = Scope();

            }

            return scope.Resolve(type);

        }


        /// <summary>

        /// Resolve all

        /// </summary>

        /// <typeparam name="T">Type</typeparam>

        /// <param name="key">key</param>

        /// <param name="scope">Scope; pass null to automatically resolve the current scope</param>

        /// <returns>Resolved services</returns>

        public virtual T[] ResolveAll<T>(string key = "", ILifetimeScope scope = null)

        {

            if (scope == null)

            {

                //no scope specified

                scope = Scope();

            }

            if (string.IsNullOrEmpty(key))

            {

                return scope.Resolve<IEnumerable<T>>().ToArray();

            }

            return scope.ResolveKeyed<IEnumerable<T>>(key).ToArray();

        }


        /// <summary>

        /// Resolve unregistered service

        /// </summary>

        /// <typeparam name="T">Type</typeparam>

        /// <param name="scope">Scope; pass null to automatically resolve the current scope</param>

        /// <returns>Resolved service</returns>

        public virtual T ResolveUnregistered<T>(ILifetimeScope scope = null) where T : class

        {

            return ResolveUnregistered(typeof(T), scope) as T;

        }


        /// <summary>

        /// Resolve unregistered service

        /// </summary>

        /// <param name="type">Type</param>

        /// <param name="scope">Scope; pass null to automatically resolve the current scope</param>

        /// <returns>Resolved service</returns>

        public virtual object ResolveUnregistered(Type type, ILifetimeScope scope = null)

        {

            if (scope == null)

            {

                //no scope specified

                scope = Scope();

            }

            var constructors = type.GetConstructors();

            foreach (var constructor in constructors)

            {

                try

                {

                    var parameters = constructor.GetParameters();

                    var parameterInstances = new List<object>();

                    foreach (var parameter in parameters)

                    {

                        var service = Resolve(parameter.ParameterType, scope);

                        if (service == null) throw new Exception("Unknown dependency");

                        parameterInstances.Add(service);

                    }

                    return Activator.CreateInstance(type, parameterInstances.ToArray());

                }

                catch (Exception)

                {


                }

            }

            throw new Exception("No constructor  was found that had all the dependencies satisfied.");

        }


        /// <summary>

        /// Try to resolve srevice

        /// </summary>

        /// <param name="serviceType">Type</param>

        /// <param name="scope">Scope; pass null to automatically resolve the current scope</param>

        /// <param name="instance">Resolved service</param>

        /// <returns>Value indicating whether service has been successfully resolved</returns>

        public virtual bool TryResolve(Type serviceType, ILifetimeScope scope, out object instance)

        {

            if (scope == null)

            {

                //no scope specified

                scope = Scope();

            }

            return scope.TryResolve(serviceType, out instance);

        }


        /// <summary>

        /// Check whether some service is registered (can be resolved)

        /// </summary>

        /// <param name="serviceType">Type</param>

        /// <param name="scope">Scope; pass null to automatically resolve the current scope</param>

        /// <returns>Result</returns>

        public virtual bool IsRegistered(Type serviceType, ILifetimeScope scope = null)

        {

            if (scope == null)

            {

                //no scope specified

                scope = Scope();

            }

            return scope.IsRegistered(serviceType);

        }


        /// <summary>

        /// Resolve optional

        /// </summary>

        /// <param name="serviceType">Type</param>

        /// <param name="scope">Scope; pass null to automatically resolve the current scope</param>

        /// <returns>Resolved service</returns>

        public virtual object ResolveOptional(Type serviceType, ILifetimeScope scope = null)

        {

            if (scope == null)

            {

                //no scope specified

                scope = Scope();

            }

            return scope.ResolveOptional(serviceType);

        }


        /// <summary>

        /// Get current scope

        /// </summary>

        /// <returns>Scope</returns>

        public virtual ILifetimeScope Scope()

        {

            try

            {

                //when such lifetime scope is returned, you should be sure that it'll be disposed once used (e.g. in schedule tasks)

                return Container.BeginLifetimeScope();

            }

            catch (Exception)

            {

                //we can get an exception here if RequestLifetimeScope is already disposed

                //for example, requested in or after "Application_EndRequest" handler

                //but note that usually it should never happen


                //when such lifetime scope is returned, you should be sure that it'll be disposed once used (e.g. in schedule tasks)

                return Container.BeginLifetimeScope(MatchingScopeLifetimeTags.RequestLifetimeScopeTag);

            }

        }

    }

使用介绍

public IServiceProvider ConfigureServices(IServiceCollection services){services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());services.AddMvc();         
    
return IocManager.Instance.Initialize(services);}

特殊场景介绍

通过上面的封装后,我们可以把Controller的注册单独出来

/// <summary>

    /// 

    /// </summary>

    public class ControllerRegistrar : IDependencyRegistrar

    {

        /// <summary>

        /// 

        /// </summary>

        public int Order

        {

            get

            {

                return 0;

            }

        }


        /// <summary>

        /// 

        /// </summary>

        /// <param name="builder"></param>

        /// <param name="listType"></param>

        public void Register(ContainerBuilder builder, List<Type> listType)

        {

            builder.RegisterType(typeof(LogInterceptor));

            //注册Controller,实现属性注入

            var IControllerType = typeof(ControllerBase);

            var arrControllerType = listType.Where(t => IControllerType.IsAssignableFrom(t) && t != IControllerType).ToArray();

            builder.RegisterTypes(arrControllerType).PropertiesAutowired().EnableClassInterceptors();

        }

    }

下面介绍几种特殊使用方式

1.创建实例时给指定参数赋值

builder.RegisterType(typeof(TestDemo)).AsSelf();

  

public class TestDemo

    {

        private readonly string _name;


        private readonly string _sex;


        private readonly int _age;


        public TestDemo(string name, string sex, int age)

        {

            _name = name;

            _age = age;

            _sex = sex;

        }

        public string Sex

        {

            get

            {

                return _sex;

            }

        }


        public string Name

        {

            get

            {

                return _name;

            }

        }


        public int Age

        {

            get

            {

                return _age;

            }

        }

    }

使用示例

var iocManager = app.ApplicationServices.GetService<IIocManager>();

List<Parameter> cparams = new List<Parameter>();

cparams.Add(new NamedParameter("name", "张三"));

cparams.Add(new NamedParameter("sex", "男"));

cparams.Add(new TypedParameter(typeof(int), 2));

var testDemo = iocManager.Resolve<TestDemo>(cparams.ToArray());

Console.WriteLine($"姓名:{testDemo.Name},年龄:{testDemo.Age},性别:{testDemo.Sex}");

 2.对象激活事件

 Autofac暴露五个事件接口供实例的按如下顺序调用

  1. OnRegistered

  2. OnPreparing

  3. OnActivated

  4. OnActivating

  5. OnRelease

 这些事件会在注册的时候被订阅,或者被附加到IComponentRegistration 的时候。

  builder.RegisterType(typeof(TestDemo)).AsSelf().OnRegistered(e => Console.WriteLine("OnRegistered在注册的时候调用!")).OnPreparing(e => Console.WriteLine("OnPreparing在准备创建的时候调用!")).OnActivating(e => Console.WriteLine("OnActivating在创建之前调用!")).OnActivated(e => Console.WriteLine("OnActivated创建之后调用!")).OnRelease(e => Console.WriteLine("OnRelease在释放占用的资源之前调用!"));

可以在这些事件里面做些特殊场景处理

总结

      本篇介绍了Autofac在项目中的使用方式以及几种特殊使用场景。其它未介绍知识如生命周期请参考http://autofac.readthedocs.io/en/latest/getting-started/index.html。

相关文章:

  • ASP.NET Core依赖注入解读&使用Autofac替代实现

  • Autofac+Castle实现AOP事务

原文地址:http://www.cnblogs.com/yanweidie/p/autofac.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/321811.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微软重组变两大事业部:Windows主管离职

微软CEO纳德拉通过内部邮件宣布&#xff0c;整个公司进行重大重组&#xff0c;划分为两个新的事业部(部门)&#xff0c;同时Windows业务主管Terry Myerson(特里梅尔森)将离开微软。Terry Myerson最为人诟病的就是推倒了Windows Mobile而打造全新的Windows Phone&#xff0c;结果…

41、java应用占用cpu过高原因分析

线上服务器cpu占用过高问题排查 1、定位最耗cpu的进程 命令&#xff1a;top 2、定位最耗cpu的线程 命令&#xff1a;Top –Hp PID 例如&#xff1a;Top –Hp 12086 3、打印线程堆栈信息 命令&#xff1a;Printf ‘%x\n’ PID 例如&#xff1a;printf ‘%x\n’ 12118 先将…

Google Optimization Tools介绍

Google Optimization Tools(OR-Tools)是一款专门快速而便携地解决组合优化问题的套件。它包含了&#xff1a;约束编程求解器。简单而统一的接口&#xff0c;用于多种线性规划和混合整数规划求解&#xff0c;包括 CBC、CLP、GLOP、GLPK、Gurobi、CPLEX 和SCIP。图算法 (最短路径…

11、mysql数据表中数据的查询(3)

说一下子查询&#xff0c;子查询的意义就是使用一个查询语句做为另一个查询语句的条件&#xff0c;一般使用exists和in来引导子查询 exists子查询 exists 放在 where 之后使用&#xff0c;可以看成查询数据所满足的一个条件&#xff0c;只是这个条件的值比较特殊&#xff08;…

使用.Net Core与Google Optimization Tools实现员工排班计划Scheduling

上一篇说完《Google Optimization Tools介绍》&#xff0c;让大家初步了解了Google Optimization Tools是一款约束求解&#xff08;CP&#xff09;的高效套件。那么我们用.Net Core与Google Optimization Tools来实现一个有关员工排班计划的场景感受一下。众所周知&#xff0c;…

42、Java服务内存OOM原因分析

1、出现问题的可能原因 对于应用来说内存分配太少 对象创建太多&#xff0c;又没有释放&#xff0c;造成内存泄漏严重&#xff0c;导致内存耗尽 申请太多的系统资源&#xff0c;系统资源耗尽。例如&#xff1a;不断创建线程&#xff0c;不断发起网络连接 2、如何定位问题&a…

Slickflow.NET 开源工作流引擎基础介绍-.NET Core2.0 版本实现介绍

前言&#xff1a;.NET Core 是.NET Framework的新一代版本&#xff0c;是微软开发的第一个跨平台 (Windows、Mac OSX、Linux) 的应用程序开发框架&#xff08;Application Framework&#xff09;&#xff0c;未来也将会支持 FreeBSD 与 Alpine 平台。.Net Core也是微软在一开始…

DotNetty 跨平台的网络通信库

久以来,.Net开发人员都非常羡慕Java有Netty这样&#xff0c;高效&#xff0c;稳定又易用的网络通信基础框架。终于微软的Azure团队&#xff0c;使用C#实现的Netty的版本发布。不但使用了C#和.Net平台的技术特点&#xff0c;并且保留了Netty原来绝大部分的编程接口。让我们在使用…

26、临时表的创建和重复数据的处理

UPDATE student b SET b.sname dd WHERE b.id (SELECT a.id FROM student a WHERE a.id 3) Mysql中根据条件&#xff08;表A中的字段&#xff09;操作表A中的数据时是不可以的 所以借助临时表来删除/更新重复的数据&#xff0c;原理就是删除每组重复数据中除id值最大的其他…

1、java简介

关于java介绍也没什么好说的&#xff0c;在这里简单介绍一下&#xff0c;说起java&#xff0c;我第一想到的就是它的简单和强大&#xff0c;简单是简单易学&#xff0c;开发速度快&#xff1b;强大是其功能强大&#xff0c;各个领域都可使用&#xff0c;其代码一次编译可以处处…

C# 观察者模式 以及 delegate 和 event

观察者模式这里面综合了几本书的资料.需求有这么个项目: 需求是这样的:一个气象站, 有三个传感器(温度, 湿度, 气压), 有一个WeatherData对象, 它能从气象站获得这三个数据. 还有三种设备, 可以按要求展示气象站的最新数据.WeatherData的结构如下:有3个get方法, 分别获取最新的…

2、JAVA开发环境的搭建

上次说到java应用之所以做到跨平台&#xff0c;是因为其依赖于java虚拟机&#xff0c;java想要运行需要依赖于特定的运行环境&#xff0c;称为JRE&#xff0c;如果想要开发java应用&#xff0c;则需要用到开发工具包&#xff0c;也就是JDK&#xff0c;所以这里就要说一下这几者…

Serilog Tutorial

在过去的几年中&#xff0c;结构化日志已经大受欢迎。而Serilog是 .NET 中最著名的结构化日志类库 ,我们提供了这份的精简指南来帮助你快速了解并运用它。0. 内容设定目标认识Serilog事件和级别触发和收集结构化数据为过滤和关联添加事件标记大海捞针 [Finding needles in the …

使用DDD、事件风暴和Actor来设计反应式系统

领域驱动设计&#xff08;domain-driven design&#xff0c;DDD&#xff09;通常在微服务领域用于查找边界&#xff08;限界上下文&#xff09;。同样来自DDD的聚合&#xff08;aggregate&#xff09;对于定义持久化和一致性的范围来讲也是很重要的。 但是&#xff0c;并不是领…

站在巨人肩上的.NET Core 2.1

.NET Core 1.0自发布两年以来&#xff0c;得到了开发者群体相当高地认可。 下图来自Stack overflow survey 2018的统计&#xff1a;.NET Core已经成为前五的主流框架工具&#xff0c;现今借鉴了优秀的设计原则和开发体验可谓站在巨人肩上。这一切归功于.NET团队认识和总结了大量…

5、java中的数组

1、简介 数组是一种具有随机存取特性的数据结构&#xff0c;是内存上一段连续区域的表示&#xff0c;是实现顺序存储的基础&#xff0c;数组只能用于存储同一类型的数据。数组的长度在初始化时定义之后就不可更改&#xff0c;并且在初始化数组时必须指定数组的长度。 2、数组…

动态规划训练19、最短路 [Help Jimmy POJ - 1661 ]

Help Jimmy POJ - 1661 题意&#xff1a;大致是一个人从某个点开始下落&#xff0c;下落的速度是1m/s&#xff0c;然后在平台上的时候可以左右移动&#xff0c;移动的速度也是1m/s&#xff0c;但是这里有一个限制&#xff0c;就是说每次下落的距离不能超过一个给定的数值。问你…

【活动(北京)】Global Azure Bootcamp

活动议程活动内容08:30-08:50报到08:50-09:10活動开场Study4 - 陈科融(MVP)STB Chain Foundation - 劉海峰(MVP)MVP Program - Christina Liang(MVP CPM)09:10-10:00区块链让软件资产化成为现实刘海峰(MVP) - STBChain Foundation主席10:10-11:00基于Azure PaaS的网站应用刘元纶…

6、java中的排序算法

1、简介 排序是将元素按着指定关键字的大小递增或递减进行数据的排列&#xff0c;排序可以提高查找的效率 2、排序算法的分类 排序算法可大致分为四类七种&#xff0c;具体分类如下&#xff1a; 插入排序&#xff1a;直接插入排序、希尔排序 交换排序&#xff1a;冒泡排序、…

用.NET Core实现装饰模式和.NET Core的Stream简介

该文章综合了几本书的内容.某咖啡店项目的解决方案某咖啡店供应咖啡, 客户买咖啡的时候可以添加若干调味料, 最后要求算出总价钱.Beverage是所有咖啡饮料的抽象类, 里面的cost方法是抽象的. description变量在每个子类里面都需要设置(表示对咖啡的描述).每个子类实现cost方法, …