概述
创建一个简单的.net core 框架程序
最近项目比较紧张,抽空学习了一下框架是怎么搭建的,学习的比较零碎,学习的地方比较多,遇到的问题也是比较多的,自己学习是比较乏味枯燥的过程,学习还是断断续续的,遇到的难点踩坑比较多,过程是比较痛苦的。现在.net core跨平台已经适用于生产环境中去了,我也是在慢慢的研究了一下,并没有去系统的学习,用到什么就学习什么这种状态,记录一下;
第一步先创建一个.net Core MVC项目
第二步创建一些类库
Application:是应用服务层
Core:是实体模型层
EFWork:是连接上下文和仓储服务层
现在互相引用一下,关系如下
先在Core类库中创建一个实体类和一个抽象类
抽象类里面添加一些常用的字段
抽象类
public abstract class EntityBase
{
public EntityBase()
{
CreateTime = DateTime.Now;
}
[Key]
public int Id { get; set; }
public DateTime CreateTime { get; set; }
}
一个用户实体并且继承EntityBase
public class Users : EntityBase
{
[StringLength(20)]
public string UserName { get; set; }
[StringLength(20, MinimumLength = 6)]
public string Password { get; set; }
}
然后在EFWork中引用EntityFrameworkCore和Microsoft.EntityFrameworkCore.SqlServer因为我使用的数据库是Microsoft SQL Server 就用EF这套来连接操作数据库(其他数据库也有异曲同工之妙)
操作完毕开始连接数据库和手写仓储方法
在EFWork中创建一个连接数据库的上下文
public class WebDbContext:DbContext
{
public DbSet<Users> users { get; set; }
public WebDbContext(DbContextOptions<WebDbContext> options) : base(options)
{
}
}
然后创建Repository类和IRepository接口类
public class Repository<TEntity, TDbContext> : IRepository<TEntity> where TEntity : class
{
private readonly WebDbContext dbContext;
public Repository(WebDbContext _dbContext)
{
dbContext = _dbContext;
}
/// <summary>
/// 新增数据
/// </summary>
/// <param name="entity">实体</param>
/// <returns></returns>
public TEntity Add(TEntity entity)
{
var result = dbContext.Set<TEntity>().Add(entity).Entity;
dbContext.SaveChanges();
return result;
}
/// <summary>
/// 异步新增数据
/// </summary>
/// <param name="entity">实体</param>
/// <returns></returns>
public async Task<TEntity> AddAsync(TEntity entity)
{
var result = (await dbContext.Set<TEntity>().AddAsync(entity)).Entity;
await dbContext.SaveChangesAsync();
return result;
}
/// <summary>
/// 删除数据
/// </summary>
/// <param name="entity">实体</param>
public int Delete(TEntity entity)
{
dbContext.Set<TEntity>().Remove(entity);
dbContext.Entry(entity).State = Microsoft.EntityFrameworkCore.EntityState.Deleted;
return dbContext.SaveChanges();
}
/// <summary>
/// 异步删除数据
/// </summary>
/// <param name="entity">实体</param>
/// <returns></returns>
public async Task<int> DeleteAsync(TEntity entity)
{
return await Task.FromResult(Delete(entity));
}
/// <summary>
/// 更新数据
/// </summary>
/// <param name="entity">实体</param>
/// <returns></returns>
public TEntity Update(TEntity entity)
{
var result = dbContext.Set<TEntity>().Update(entity).Entity;
dbContext.Entry(entity).State = Microsoft.EntityFrameworkCore.EntityState.Detached;
dbContext.SaveChanges();
return result;
}
/// <summary>
/// 异步更新数据
/// </summary>
/// <param name="entity">实体</param>
/// <returns></returns>
public async Task<TEntity> UpdateAsync(TEntity entity)
{
var result = await Task.FromResult(Update(entity));
return result;
}
/// <summary>
/// 通过拉姆达表达式查找数据
/// </summary>
/// <param name="predicate">表达式</param>
/// <returns></returns>
public IEnumerable<TEntity> GetAll(Func<TEntity, bool> predicate)
{
return dbContext.Set<TEntity>().Where(predicate);
}
/// <summary>
/// 异步通过拉姆达表达式查找数据
/// </summary>
/// <param name="predicate">表达式</param>
/// <returns></returns>
public async Task<IEnumerable<TEntity>> GetAllList(Func<TEntity, bool> predicate)
{
return await Task.FromResult(GetAll(predicate));
}
/// <summary>
/// 通过分页查询数据
/// </summary>
/// <param name="predicateOrder">正序排列条件</param>
/// <param name="predicate">查询条件</param>
/// <param name="Count">返回条数</param>
/// <param name="PageIndex">页码</param>
/// <param name="PageSize">页的大小</param>
/// <returns></returns>
public IEnumerable<TEntity> PageRequestResult(Func<TEntity, bool> predicateOrder, Func<TEntity, bool> predicate, out int Count, int PageIndex = 1, int PageSize = 10)
{
var result = dbContext.Set<TEntity>().Where(predicate).OrderBy(predicateOrder).Take((PageIndex - 1) * PageSize).Skip(PageSize);
Count = result.Count();
return result;
}
/// <summary>
/// 其他方法扩展
/// </summary>
/// <returns></returns>
public DbSet<TEntity> OtherExtend()
{
var result = dbContext.Set<TEntity>();
return result;
}
}
public interface IRepository<TEntity> where TEntity : class
{
/// <summary>
/// 新增数据
/// </summary>
/// <param name="entity">实体</param>
/// <returns></returns>
TEntity Add(TEntity entity);
/// <summary>
/// 异步新增数据
/// </summary>
/// <param name="entity">实体</param>
/// <returns></returns>
Task<TEntity> AddAsync(TEntity entity);
/// <summary>
/// 删除数据
/// </summary>
/// <param name="entity">实体</param>
int Delete(TEntity entity);
/// <summary>
/// 异步删除数据
/// </summary>
/// <param name="entity">实体</param>
/// <returns></returns>
Task<int> DeleteAsync(TEntity entity);
/// <summary>
/// 更新数据
/// </summary>
/// <param name="entity">实体</param>
/// <returns></returns>
TEntity Update(TEntity entity);
/// <summary>
/// 异步更新数据
/// </summary>
/// <param name="entity">实体</param>
/// <returns></returns>
Task<TEntity> UpdateAsync(TEntity entity);
/// <summary>
/// 通过拉姆达表达式查找数据
/// </summary>
/// <param name="predicate">表达式</param>
/// <returns></returns>
IEnumerable<TEntity> GetAll(Func<TEntity, bool> predicate);
/// <summary>
/// 异步通过拉姆达表达式查找数据
/// </summary>
/// <param name="predicate">表达式</param>
/// <returns></returns>
Task<IEnumerable<TEntity>> GetAllList(Func<TEntity, bool> predicate);
/// <summary>
/// 通过分页查询数据
/// </summary>
/// <param name="predicateOrder">正序排列条件</param>
/// <param name="predicate">查询条件</param>
/// <param name="Count">返回条数</param>
/// <param name="PageIndex">页码</param>
/// <param name="PageSize">页的大小</param>
/// <returns></returns>
IEnumerable<TEntity> PageRequestResult(Func<TEntity, bool> predicateOrder, Func<TEntity, bool> predicate, out int Count, int PageIndex = 1, int PageSize = 10);
/// <summary>
/// 其他方法扩展
/// </summary>
/// <returns></returns>
DbSet<TEntity> OtherExtend();
仓储内的方法只写了一些,也可以自由扩展一下
然后迁移数据库,先在appsettings.json中配置数据库
{
"ConnectionStrings": {
"DefaultConnection": "Server=.;Database=EFWorkDB;Trusted_Connection=True;MultipleActiveResultSets=true"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
在Startup中配置service
public void ConfigureServices(IServiceCollection services)
{
//注册DbConfig,连接数据库
services.AddDbContext<WebDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
//添加数据库异常筛选器 需要下载Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore,并且引用
services.AddDatabaseDeveloperPageExceptionFilter();
services.AddControllersWithViews();
}
找到命令控制台选择默认项目为EFWork项目,然后安装数据迁移命令库Install-Package Microsoft.EntityFrameworkCore.Tools
在mvc项目中安装包Install-Package Microsoft.EntityFrameworkCore.Design
Add-Migration 命令会通知迁移框架使用当前 DB 架构检查当前 users 模型,并创建必要的代码,将 DB 迁移到新模型。
Update-Database更新数据库
迁移成功后可以查看数据库是否正确,迁移过程中可能会缺少一些相应的库,在nuget上下载即可;
然后我们在Application项目中添加我们的服务,添加一个ApplicationModule类添加一些相关的方法
public class AsyncCrudAppService<TEntity> : IAsyncCrudAppService<TEntity> where TEntity : class
{
private readonly IRepository<TEntity> repository;
public AsyncCrudAppService(IRepository<TEntity> _repository)
{
repository = _repository;
}
/// <summary>
/// 新增数据
/// </summary>
/// <param name="entity">实体</param>
/// <returns></returns>
public TEntity Add(TEntity entity)
{
var result = repository.Add(entity);
return result;
}
/// <summary>
/// 异步新增数据
/// </summary>
/// <param name="entity">实体</param>
/// <returns></returns>
public async Task<TEntity> AddAsync(TEntity entity)
{
var result = await repository.AddAsync(entity);
return result;
}
/// <summary>
/// 删除数据
/// </summary>
/// <param name="entity">实体</param>
public int Delete(TEntity entity)
{
return repository.Delete(entity);
}
/// <summary>
/// 异步删除数据
/// </summary>
/// <param name="entity">实体</param>
/// <returns></returns>
public async Task<int> DeleteAsync(TEntity entity)
{
return await repository.DeleteAsync(entity);
}
/// <summary>
/// 更新数据
/// </summary>
/// <param name="entity">实体</param>
/// <returns></returns>
public TEntity Update(TEntity entity)
{
var result = repository.Update(entity);
return result;
}
/// <summary>
/// 异步更新数据
/// </summary>
/// <param name="entity">实体</param>
/// <returns></returns>
public async Task<TEntity> UpdateAsync(TEntity entity)
{
var result = await repository.UpdateAsync(entity);
return result;
}
/// <summary>
/// 通过拉姆达表达式查找数据
/// </summary>
/// <param name="predicate">表达式</param>
/// <returns></returns>
public IEnumerable<TEntity> GetAll(Func<TEntity, bool> predicate)
{
return repository.GetAll(predicate);
}
/// <summary>
/// 异步通过拉姆达表达式查找数据
/// </summary>
/// <param name="predicate">表达式</param>
/// <returns></returns>
public async Task<IEnumerable<TEntity>> GetAllList(Func<TEntity, bool> predicate)
{
return await repository.GetAllList(predicate);
}
/// <summary>
/// 通过分页查询数据
/// </summary>
/// <param name="predicateOrder">正序排列条件</param>
/// <param name="predicate">查询条件</param>
/// <param name="Count">返回条数</param>
/// <param name="PageIndex">页码</param>
/// <param name="PageSize">页的大小</param>
/// <returns></returns>
public IEnumerable<TEntity> PageRequestResult(Func<TEntity, bool> predicateOrder, Func<TEntity, bool> predicate, out int Count, int PageIndex = 1, int PageSize = 10)
{
var result = repository.PageRequestResult(predicateOrder,predicate,out Count,PageIndex,PageSize);
return result;
}
}
public interface IAsyncCrudAppService<TEntity> where TEntity : class
{
/// <summary>
/// 新增数据
/// </summary>
/// <param name="entity">实体</param>
/// <returns></returns>
TEntity Add(TEntity entity);
/// <summary>
/// 异步新增数据
/// </summary>
/// <param name="entity">实体</param>
/// <returns></returns>
Task<TEntity> AddAsync(TEntity entity);
/// <summary>
/// 删除数据
/// </summary>
/// <param name="entity">实体</param>
int Delete(TEntity entity);
/// <summary>
/// 异步删除数据
/// </summary>
/// <param name="entity">实体</param>
/// <returns></returns>
Task<int> DeleteAsync(TEntity entity);
/// <summary>
/// 更新数据
/// </summary>
/// <param name="entity">实体</param>
/// <returns></returns>
TEntity Update(TEntity entity);
/// <summary>
/// 异步更新数据
/// </summary>
/// <param name="entity">实体</param>
/// <returns></returns>
Task<TEntity> UpdateAsync(TEntity entity);
/// <summary>
/// 通过拉姆达表达式查找数据
/// </summary>
/// <param name="predicate">表达式</param>
/// <returns></returns>
IEnumerable<TEntity> GetAll(Func<TEntity, bool> predicate);
/// <summary>
/// 异步通过拉姆达表达式查找数据
/// </summary>
/// <param name="predicate">表达式</param>
/// <returns></returns>
Task<IEnumerable<TEntity>> GetAllList(Func<TEntity, bool> predicate);
/// <summary>
/// 通过分页查询数据
/// </summary>
/// <param name="predicateOrder">正序排列条件</param>
/// <param name="predicate">查询条件</param>
/// <param name="Count">返回条数</param>
/// <param name="PageIndex">页码</param>
/// <param name="PageSize">页的大小</param>
/// <returns></returns>
IEnumerable<TEntity> PageRequestResult(Func<TEntity, bool> predicateOrder, Func<TEntity, bool> predicate, out int Count, int PageIndex = 1, int PageSize = 10);
}
这个类中的相应代码,主要时为了减少代码的重复操作
我们在Sevcies和IService中继承这两个类就行了
Service
public class UserService : AsyncCrudAppService<Users>, IUserService
{
private readonly IRepository<Users> repository;
public UserService(IRepository<Users> _repository) : base(_repository)
{
}
}
IService
public interface IUserService : IAsyncCrudAppService<Users>
{
}
然后我们需要在Startup中注册相关项
services.AddScoped<IRepository<Users>, Repository<Users>>();
services.AddScoped<IAsyncCrudAppService<Users>, AsyncCrudAppService<Users>>();
services.AddScoped<IUserService, UserService>();
在HomeController中添加一些功能
写了获取数据和添加数据功能,其他功能可以自由扩展,就不一一列出了
基本的操作已经做完了
接下来就是登录的了
先创建一个AccountController控制器,然后在Startup中配置注册权限过滤
//身份验证注册
app.UseAuthentication();
再全局注册权限验证机制和登录时的Cookie信息
//在 Startup.ConfigureServices 方法中,创建具有和方法的身份验证中间件服务 AddAuthentication AddCookie
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
//没有登陆时,将会将请求重定向到这个相对路径
options.LoginPath = new PathString("/Account/Login");
//登录后cookie的名称
options.Cookie.Name = "My_Cookie";
//没有访问权限时,将会将请求重定向到这个相对路径
options.AccessDeniedPath = new PathString("/Home/Error");
});
//全局加入身份验证
services.AddMvc(options => options.Filters.Add(new AuthorizeFilter())).SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
在视图Login中创建登录页面
@model LoginViewModel
@{ Layout = null; }
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
<div class="row">
<div class="col-md-8">
<form asp-action="Login">
<input type="hidden" name="returnUrl" value="@ViewBag.ReturnUrl" />
<h4>帐户登录</h4>
<hr />
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Email" class="control-label"></label>
<input asp-for="Email" class="form-control" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Password" class="control-label"></label>
<input asp-for="Password" type="password" class="form-control" />
<span asp-validation-for="Password" class="text-danger"></span>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<div class="checkbox">
@Html.CheckBoxFor(m => m.RememberMe)
@Html.LabelFor(m => m.RememberMe)
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="登录" class="btn btn-success" />
</div>
</div>
</form>
</div>
</div>
@section Scripts {
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}
//登录的model
public class LoginViewModel
{
[Required]
[Display(Name = "电子邮件")]
[EmailAddress]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "密码")]
public string Password { get; set; }
[Display(Name = "记住我?")]
public bool RememberMe { get; set; }
}
我们登录的Controller如下
public class AccountController : Controller
{
[AllowAnonymous]
public IActionResult Login(string returnUrl)
{
if (string.IsNullOrWhiteSpace(returnUrl))
{
returnUrl = GetAppHomeUrl();
}
ViewBag.ReturnUrl = returnUrl;
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl)
{
if (model.Email.Equals("admin@admin.com") && model.Password.Equals("123qwe"))
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, model.Email),
};
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), new AuthenticationProperties
{
IsPersistent = true,
RedirectUri = returnUrl,
ExpiresUtc = DateTime.Now.AddSeconds(5)//每访问一下页面会添加一下访问时间,如果时间到期,会跳转到登录页面
});
return RedirectToLocal(returnUrl);
}
else
{
return View();
}
}
public async Task<IActionResult> LogOut()
{
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return RedirectToAction("Login");
}
/// <summary>
/// 重定项
/// </summary>
/// <param name="returnUrl"></param>
/// <returns></returns>
private ActionResult RedirectToLocal(string returnUrl)
{
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
return RedirectToAction("Index", "Home");
}
public string GetAppHomeUrl()
{
return Url.Action("Index", "Home");
}
}
到此为止现在的框架基本都差不多了,适合小型项目的使用了,但是还有一个问题就是如果咱们的实体类过多的情况下,需要依赖注入代码量庞大,所以咱们要写一个通用的方法来批量依赖注入,现在来看依赖注入的代码
/// <summary>
/// 先创建一个抽象类
/// </summary>
public abstract class IocManager
{
public static void Register(IServiceCollection services)
{
Type type = typeof(IDependency);//获取继承IDependency的类型
//从程序集中找到包含IDependency所有相关
var Types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces().Contains(type) || t.GetInterfaces().Contains(type)));
//得到类的集合
var classList = Types.Where(o => o.IsClass).ToList();
//得到接口的集合
var InterfaceList = Types.Where(o => o.IsInterface).ToList();
foreach (var item in classList)
{
var firstInterface = InterfaceList.FirstOrDefault(o => o.IsAssignableFrom(item));//class有接口,注入接口和类
if (firstInterface != null)
{
services.AddScoped(firstInterface, item);
}
else
{
//注入class
services.AddScoped(item);
}
}
//派生类注入
services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
services.AddScoped(typeof(IAsyncCrudAppService<>), typeof(AsyncCrudAppService<>));
}
}
在Startup.ConfigureServices中注入
//批量依赖注入
IocManager.Register(services);
创建一个IDependency接口
public interface IDependency
{
}
在我们的IService中继承IDependency
public interface IUserService : IAsyncCrudAppService<Users>, IDependency
{
}
就到此结束结束了
最后
以上就是怕孤单小懒虫为你收集整理的# 创建一个简单的.net core 框架程序创建一个简单的.net core 框架程序的全部内容,希望文章能够帮你解决# 创建一个简单的.net core 框架程序创建一个简单的.net core 框架程序所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复