.Net基础1

.NET框架

项目结构

在这里插入图片描述

  • Connected Services是第三方服务
  • MVC框架
  • appsettings.json配置文件
  • Program.cs控制台应用程序
  • Properties里的json文件是配置启动方式

1. 基本开发

在这里插入图片描述

出现这个bug是因为防火墙没有把浏览器加入白名单,可以暂时先用http启动代替

  • 第一步创建控制器(请求映射路径就是文件夹和文件名)
  • 第二步在该控制器右键新建视图
  • 启动
  • 数据返回方式
//控制器
public IActionResult Index()
{
    ViewBag.User1 = "张三";
    ViewData["User2"] = "李四";
    TempData["User3"] = "王五";
    HttpContext.Session.SetString("User4", "赵六");
    object User5 = "田七";
    return View(User5);
}
//视图
@{
    ViewData["Title"] = "Hello,World";
}
@Model String
<h2>User1=@ViewBag.User1</h2>
<h2>User2=@ViewData["User2"]</h2>
<h2>User3=@TempData["User3"]</h2>
<h2>User4=@Context.Session.GetString("User4")</h2>
<h2>User5=@Model</h2>
//如果不配置Session服务就会报错
//到Program里面配置
builder.Service.AddSession();
var app = builder.Build();
app.UseSession();

2.日志log4net组件整合

导入依赖包

  • 右键 => 管理解决方案
    在这里插入图片描述

  • 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 另外还要安装第二个组件Log4Net.AspNetCore

  • 可以在依赖项里看到安装好的包

配置文件

  • 文件结构(XML):<Log4Net,,>

    • <?xml version="1.0" encoding="utf-8"?>
      <log4net>
      	<!-- Define some output appenders -->
      	<appender name="rollingAppender" type="log4net.Appender.RollingFileAppender">
      		<file value="log4\log.txt" />
      		<!--追加日志内容-->
      		<appendToFile value="true" />
      
      		<!--防止多线程时不能写Log,官方说线程非安全-->
      		<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
      
      		<!--可以为:Once|Size|Date|Composite-->
      		<!--Composite为Size和Date的组合-->
      		<rollingStyle value="Composite" />
      
      		<!--当备份文件时,为文件名加的后缀-->
      		<datePattern value="yyyyMMdd.TXT" />
      
      		<!--日志最大个数,都是最新的-->
      		<!--rollingStyle节点为Size时,只能有value个日志-->
      		<!--rollingStyle节点为Composite时,每天有value个日志-->
      		<maxSizeRollBackups value="20" />
      
      		<!--可用的单位:KB|MB|GB-->
      		<maximumFileSize value="3MB" />
      
      		<!--置为true,当前最新日志文件名永远为file节中的名字-->
      		<staticLogFileName value="true" />
      
      		<!--输出级别在INFO和ERROR之间的日志-->
      		<filter type="log4net.Filter.LevelRangeFilter">
      			<param name="LevelMin" value="ALL" />
      			<param name="LevelMax" value="FATAL" />
      		</filter>
      		<layout type="log4net.Layout.PatternLayout">
      			<conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/>
      		</layout>
      	</appender>
      
      	<!--SqlServer形式-->
      	<!--log4net日志配置:http://logging.apache.org/log4net/release/config-examples.html -->
      	<appender name="AdoNetAppender_SqlServer" type="log4net.Appender.AdoNetAppender">
      		<!--日志缓存写入条数 设置为0时只要有一条就立刻写到数据库-->
      		<bufferSize value="0" />
      		<connectionType value="System.Data.SqlClient.SqlConnection,System.Data.SqlClient, Version=4.6.1.3, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
      		<connectionString value="Data Source=PC-202206030027;Initial Catalog=LogManager;Persist Security Info=True;User ID=sa;Password=sa123" />
      		<commandText value="INSERT INTO Log4Net ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" />
      		<parameter>
      			<parameterName value="@log_date" />
      			<dbType value="DateTime" />
      			<layout type="log4net.Layout.RawTimeStampLayout" />
      		</parameter>
      		<parameter>
      			<parameterName value="@thread" />
      			<dbType value="String" />
      			<size value="255" />
      			<layout type="log4net.Layout.PatternLayout">
      				<conversionPattern value="%thread" />
      			</layout>
      		</parameter>
      		<parameter>
      			<parameterName value="@log_level" />
      			<dbType value="String" />
      			<size value="50" />
      			<layout type="log4net.Layout.PatternLayout">
      				<conversionPattern value="%level" />
      			</layout>
      		</parameter>
      		<parameter>
      			<parameterName value="@logger" />
      			<dbType value="String" />
      			<size value="255" />
      			<layout type="log4net.Layout.PatternLayout">
      				<conversionPattern value="%logger" />
      			</layout>
      		</parameter>
      		<parameter>
      			<parameterName value="@message" />
      			<dbType value="String" />
      			<size value="4000" />
      			<layout type="log4net.Layout.PatternLayout">
      				<conversionPattern value="%message" />
      			</layout>
      		</parameter>
      		<parameter>
      			<parameterName value="@exception" />
      			<dbType value="String" />
      			<size value="2000" />
      			<layout type="log4net.Layout.ExceptionLayout" />
      		</parameter>
      	</appender>
      	
      	
      	<root>
      
      		<!--控制级别,由低到高: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF-->
      		<!--OFF:0-->
      		<!--FATAL:FATAL-->
      		<!--ERROR: ERROR,FATAL-->
      		<!--WARN: WARN,ERROR,FATAL-->
      		<!--INFO: INFO,WARN,ERROR,FATAL-->
      		<!--DEBUG: INFO,WARN,ERROR,FATAL-->
      		<!--ALL: DEBUG,INFO,WARN,ERROR,FATAL--> 
      		<priority value="ALL"/>
      		
      		<level value="INFO"/>
      		<appender-ref ref="rollingAppender" />
      		<appender-ref ref="AdoNetAppender_SqlServer" />
      	</root>
      </log4net>
      
  • 右键属性,将文件设置为copy if newer 或者 copy always(在编译的时候复制到bin文件夹)

  • 在Program里导入

builder.Logging.AddLog4Net("同级目录/Log4Net.Config");
  • 调用日志接口

    • 构造函数注入
    private readonly ILogger<Controller> _ILogger; 
    public Controller(ILogger<Controller> ilogger){
        this._ILogger = ilogger;
    }
    
    • 日志记录
    _Ilogger.LogInformation("this is information");
    _ILogger.LogError("this is Error");
    _ILogger.LogWarning("this is Warning");
    _ILogger.DeBug("this is DeBug");
    

数据库日志

先安装SQLClient(相同的方法,System.Data开头的)

因为是SQL Server 没学过,暂时放着

IOC容器之第三方组件Autofac

  • 引入依赖Autofac和Autofac.Extensions.DependencyInjection都要
  • IOC的意义在于,操作的对象可以是抽象,而不是具体的实现
  • Autofac 是一个流行的依赖注入容器,它提供了许多高级功能,如自动装配、动态解析和生命周期管理。更多复杂的注入方式(属性注入、方法注入等)
  • .NET 原生的依赖注入是随着 .NET Core 的推出而引入的,它更加轻量级,易于使用,支持基本的依赖注入模式,包括构造函数注入、服务生命周期管理。
  • 单个类注入步骤
 // 创建构造器
 ContainerBuilder builder = new ContainerBuilder();

 // 注册抽象与实现的隐射
 builder.RegisterType<Print>().As<IPrint>();
 // 泛型
 builder.RegisterGeneric(typeof(List<>)).As(typeof(IList<>));

 // 构建容器
 IContainer container =  builder.Build();

 // 创建实例
 IPrint print = container.Resolve<IPrint>();
 IList<IPrint> prints = container.Resolve<IList<IPrint>>();

// 打印
 Console.WriteLine(print.ToString());
 foreach (var item in prints)
 {
     Console.WriteLine(item.ToString());
 }
 print.Print("This is Print");

// 此外还有多种注册方式(实例注册、注册逻辑)
  • 程序集注入
 //将其他程序集引入可以使用右键依赖项然后引用
// 创建构造器
ContainerBuilder builder = new ContainerBuilder();

// 假设我们有两个程序集,一个包含接口,另一个包含实现
Assembly interfaceAssembly = Assembly.LoadFrom("Interfaces.dll");//Interfaces是文件夹名称
Assembly implementationAssembly = Assembly.LoadFrom("Implementations.dll");

// 使用这个方法注册时,会扫描程序集所有的接口、实现
// 注册接口程序集中的所有接口类型
builder.RegisterAssemblyTypes(interfaceAssembly)
       .Where(t => t.IsInterface)
       .AsImplementedInterfaces();

// 注册实现程序集中的所有非接口类型(实现类)
builder.RegisterAssemblyTypes(implementationAssembly)
       .Where(t => !t.IsInterface)
       .AsImplementedInterfaces();

// 构建容器
var container = builder.Build();

// 尝试解析接口实例
var myService = container.Resolve<IMyService>();
// 其他写法
builder.RegisterAssemblyTypes(interfaceAssembly,implementationAssembly).AsImplementedInterfaces();
  • 正常注册之后,是只会完成构造器注入,如果有属性不在构造器就必须使用属性注入
 builder.RegisterType<Print>().As<IPrint>().PropertitiesAutowired;
  • 方法注入,创建实例之后,方法自动执行,参数自动注入(略)

  • 单抽象多实例,多个实现类注册,创建时默认生成最后注册的实现类

// 但也可以通过下面的方法来实现
builder.RegisterType<Print>().Keyed<IPrint>("NewPrint");
IPrint print = container.ResolveKeyed<IPrint>("NewPrint");

Autofac整合AOP

  • 引入包 Castle.Core
  • 编写相应的特性
public class CustomInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        //方法执行前
        invocation.Proceed();
        //方法执行后
    }
}
  • 放在对应的类上并且对应的方法要定义为虚拟
[Intercept(typeof(CustomInterceptor))]

public virtual void Print()
{
    Console.WriteLine("方法执行")
}
  • 注册
builder.RegisterType<Print>().As<IPrint>().EnableClassInterceptors();

整合Autofac

// Program.cs里
 builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
 builder.Host.ConfigureContainer<ContainerBuilder>(Container =>
 {
     //注册服务
 });

// 整合程序集注册、单抽象多实例和AOP编程

using Autofac;
using Autofac.Extras.DynamicProxy;
using Castle.DynamicProxy;
using System;
using System.Reflection;

// 定义接口
public interface IPrint
{
    void PrintMessage(string message);
}

// 实现类
public class PrintA : IPrint
{
    public void PrintMessage(string message)
    {
        Console.WriteLine($"PrintA: {message}");
    }
}

public class PrintB : IPrint
{
    public void PrintMessage(string message)
    {
        Console.WriteLine($"PrintB: {message}");
    }
}

// AOP 拦截器
public class CallLogger : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        Console.WriteLine($"Before: {invocation.Method.Name}");
        invocation.Proceed();
        Console.WriteLine($"After: {invocation.Method.Name}");
    }
}

class Program
{
    static void Main(string[] args)
    {
        var builder = new ContainerBuilder();

        // 程序集注入
        var assembly = Assembly.GetExecutingAssembly();
        builder.RegisterAssemblyTypes(assembly)
            .Where(t => t.Name.EndsWith("A")) // 假设以"A"结尾的类是我们要注册的
            .AsImplementedInterfaces()
            .EnableClassInterceptors();

        // 单抽象多实例注册
        builder.RegisterType<PrintA>().Keyed<IPrint>("PrintA");
        builder.RegisterType<PrintB>().Keyed<IPrint>("PrintB");

        // 注册拦截器
        builder.Register(c => new CallLogger());

        var container = builder.Build();

        // 解析并使用服务
        var printA = container.ResolveKeyed<IPrint>("PrintA");
        var printB = container.ResolveKeyed<IPrint>("PrintB");

        printA.PrintMessage("Hello from PrintA");
        printB.PrintMessage("Hello from PrintB");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值