2
0
mirror of https://github.com/esiur/esiur-dotnet.git synced 2025-06-26 21:13:13 +00:00
This commit is contained in:
2021-05-14 18:24:34 +03:00
parent 0af14009be
commit 5bf258673d
48 changed files with 1032 additions and 383 deletions

View File

@ -40,7 +40,7 @@ namespace Esiur.Stores.EntityCore
//internal object _PrimaryId;
public event DestroyedEvent OnDestroy;
public event PropertyChangedEventHandler PropertyChanged;
//public event PropertyChangedEventHandler PropertyChanged;
[NotMapped]
public Instance Instance { get; set; }
@ -66,7 +66,7 @@ namespace Esiur.Stores.EntityCore
public void Destroy()
{
//throw new NotImplementedException();
OnDestroy?.Invoke(this);
}

View File

@ -45,31 +45,25 @@ namespace Esiur.Stores.EntityCore
Dictionary<Type, Dictionary<object, WeakReference>> DB = new Dictionary<Type, Dictionary<object, WeakReference>>();
object DBLock = new object();
internal struct TypeInfo
{
public string Name;
public IEntityType Type;
public PropertyInfo PrimaryKey;
}
Dictionary<string, EntityTypeInfo> TypesByName = new Dictionary<string, EntityTypeInfo>();
internal Dictionary<Type, EntityTypeInfo> TypesByType = new Dictionary<Type, EntityTypeInfo>();
Dictionary<string, TypeInfo> TypesByName = new Dictionary<string, TypeInfo>();
internal Dictionary<Type, TypeInfo> TypesByType = new Dictionary<Type, TypeInfo>();
[Attribute]
public Func<DbContext> Getter { get; set; }
bool Loaded;
public AsyncReply<IResource> Get(string path)
{
var p = path.Split('/');
var ti = TypesByName[p[0]];
var id = Convert.ChangeType(p[1], ti.PrimaryKey.PropertyType);// Convert.ToInt32();
var id = Convert.ChangeType(p[1], ti.PrimaryKey.PropertyType);
var db = DbContextProvider();
// Get db
var db = Getter();
var res = db.Find(ti.Type.ClrType, id);
var ent = db.Entry(res);
// load navigation properties
var ent = db.Entry(res);
foreach (var rf in ent.References)
rf.Load();
@ -78,12 +72,11 @@ namespace Esiur.Stores.EntityCore
public AsyncReply<bool> Put(IResource resource)
{
if (resource is EntityStore)
if (resource == this)
return new AsyncReply<bool>(true);
var type = ResourceProxy.GetBaseType(resource);//.GetType().;
var type = ResourceProxy.GetBaseType(resource);
//var eid = (resource as EntityResource)._PrimaryId;// (int)resource.Instance.Variables["eid"];
var eid = TypesByType[type].PrimaryKey.GetValue(resource);
@ -112,11 +105,12 @@ namespace Esiur.Stores.EntityCore
}
}
[Attribute]
public Func<DbContext> DbContextProvider { get; set; }
[Attribute]
public DbContextOptionsBuilder Options { get; set; }
//public T CreateDB()
//{
//}
//DbContext dbContext;
//[Attribute]
@ -195,13 +189,17 @@ namespace Esiur.Stores.EntityCore
throw new NotImplementedException();
}
internal DbContextOptions Options { get; set; }
public AsyncReply<bool> Trigger(ResourceTrigger trigger)
{
if (trigger == ResourceTrigger.Initialize)// SystemInitialized && DbContext != null)
{
if (DbContextProvider == null)
DbContextProvider = () => Activator.CreateInstance(Options.Options.ContextType, Options.Options) as DbContext;
if (Getter == null)
throw new Exception("Getter is not set for the store.");
// DbContextProvider = () => Activator.CreateInstance(Options.Options.ContextType, Options.Options) as DbContext;
ReloadModel();
}
@ -209,21 +207,23 @@ namespace Esiur.Stores.EntityCore
return new AsyncReply<bool>(true);
}
public void ReloadModel()
void ReloadModel()
{
TypesByName.Clear();
TypesByType.Clear();
var context = DbContextProvider();// Activator.CreateInstance(Options.Options.ContextType, Options.Options) as DbContext;
var context = Getter();
var types = context.Model.GetEntityTypes();
foreach (var t in types)
{
var ti = new TypeInfo()
var ti = new EntityTypeInfo()
{
Name = t.ClrType.Name,
PrimaryKey = t.FindPrimaryKey().Properties.FirstOrDefault()?.PropertyInfo,
Type = t
Type = t,
//Getter = getter
};
TypesByName.Add(t.ClrType.Name, ti);
@ -236,7 +236,7 @@ namespace Esiur.Stores.EntityCore
public void Destroy()
{
//throw new NotImplementedException();
OnDestroy?.Invoke(this);
}
}
}

View File

@ -0,0 +1,17 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
namespace Esiur.Stores.EntityCore
{
struct EntityTypeInfo
{
public string Name;
public IEntityType Type;
public PropertyInfo PrimaryKey;
// public Func<DbContext> Getter;
}
}

View File

@ -9,10 +9,11 @@
<Product>Esiur Entity Framework Extension</Product>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageId>Esiur.Stores.EntityCore</PackageId>
<Version>1.0.2</Version>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.6" />
<PackageReference Include="System.Collections" Version="4.3.0" />
</ItemGroup>

View File

@ -34,10 +34,11 @@ using System.Linq;
using Microsoft.EntityFrameworkCore.Metadata;
using System.Reflection;
using Esiur.Proxy;
using Microsoft.EntityFrameworkCore;
namespace Esiur.Stores.EntityCore
{
public class EsiurExtensionOptions : IDbContextOptionsExtension
public class EsiurExtensionOptions : IDbContextOptionsExtension
{
//public Dictionary<Type, PropertyInfo> Cache { get; } = new Dictionary<Type, PropertyInfo>();

View File

@ -23,6 +23,9 @@ SOFTWARE.
*/
using Esiur.Core;
using Esiur.Data;
using Esiur.Misc;
using Esiur.Proxy;
using Esiur.Resource;
using Esiur.Security.Permissions;
using Microsoft.EntityFrameworkCore;
@ -31,6 +34,7 @@ using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
namespace Esiur.Stores.EntityCore
@ -43,49 +47,108 @@ namespace Esiur.Stores.EntityCore
//}
public static T AddResource<T>(this DbSet<T> dbSet, object properties = null) where T : class, IResource
=> AddResourceAsync(dbSet, properties).Wait();
public static T AddResource<T>(this DbSet<T> dbSet, T resource) where T : class, IResource
=> AddResourceAsync(dbSet, resource).Wait();
public static async AsyncReply<T> AddResourceAsync<T>(this DbSet<T> dbSet, object properties = null) where T : class, IResource
public static async AsyncReply<T> AddResourceAsync<T>(this DbSet<T> dbSet, T resource) where T : class, IResource
{
var store = dbSet.GetInfrastructure().GetService<IDbContextOptions>().FindExtension<EsiurExtensionOptions>().Store;
var manager = store.Instance.Managers.FirstOrDefault();// > 0 ? store.Instance.Managers.First() : null;
//var db = dbSet.GetService<ICurrentDbContext>().Context;
//var resource = dbSet.GetInfrastructure().CreateResource<T>(properties);
//var resource = Warehouse.New<T>("", options.Store, null, null, null, properties);
var resource = await Warehouse.New<T>("", null, null, null, null, properties);
var entity = dbSet.Add(resource);
var resType = typeof(T);
var proxyType = ResourceProxy.GetProxy(resType);
IResource res;
if (proxyType == resType)
{
res = resource;
}
else
{
res = Activator.CreateInstance(proxyType) as IResource;
var ps = Structure.FromObject(resource);
foreach (var p in ps)
{
var mi = resType.GetMember(p.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)
.FirstOrDefault();
if (mi != null)
{
if (mi is PropertyInfo)
{
var pi = mi as PropertyInfo;
if (pi.CanWrite)
{
try
{
pi.SetValue(res, p.Value);
}
catch (Exception ex)
{
Global.Log(ex);
}
}
}
else if (mi is FieldInfo)
{
try
{
(mi as FieldInfo).SetValue(res, p.Value);
}
catch (Exception ex)
{
Global.Log(ex);
}
}
}
}
}
//await Warehouse.Put<T>("", null, null, null, null, properties);
var entity = dbSet.Add((T)res);
await entity.Context.SaveChangesAsync();
var id = store.TypesByType[typeof(T)].PrimaryKey.GetValue(resource);
await Warehouse.Put(resource, id.ToString(), store, null, null, 0, manager);
await Warehouse.Put(id.ToString(), res, store, null, null, 0, manager);
return resource;
}
public static async AsyncReply<T> CreateResourceAsync<T>(this IServiceProvider serviceProvider, object properties = null) where T : class, IResource
{
var options = serviceProvider.GetService<IDbContextOptions>().FindExtension<EsiurExtensionOptions>();
//public static async AsyncReply<T> CreateResourceAsync<T>(this IServiceProvider serviceProvider, T properties = null) where T : class, IResource
//{
// var options = serviceProvider.GetService<IDbContextOptions>().FindExtension<EsiurExtensionOptions<T>>();
var resource = await Warehouse.New<T>("", options.Store, null, null, null, properties);
// var resource = await Warehouse.New<T>("", options.Store, null, null, null, properties);
resource.Instance.Managers.AddRange(options.Store.Instance.Managers.ToArray());
// resource.Instance.Managers.AddRange(options.Store.Instance.Managers.ToArray());
return resource;
}
// return resource;
//}
public static T CreateResource<T>(this IServiceProvider serviceProvider, object properties = null) where T : class, IResource
=> CreateResourceAsync<T>(serviceProvider, properties).Wait();
//public static T CreateResource<T>(this IServiceProvider serviceProvider, object properties = null) where T : class, IResource
// => CreateResourceAsync<T>(serviceProvider, properties).Wait();
public static DbContextOptionsBuilder UseEsiur(this DbContextOptionsBuilder optionsBuilder,
//DbContext context,
string name = null,
IResource parent = null,
IPermissionsManager manager = null,
Func<DbContext> dbContextProvider = null
EntityStore store,
Func<DbContext> getter = null
//IServiceCollection services = null
//string name = null,
//IResource parent = null,
//IPermissionsManager manager = null,
//Func<DbContext> dbContextProvider = null
)
{
var extension = optionsBuilder.Options.FindExtension<EsiurExtensionOptions>();
@ -93,10 +156,9 @@ namespace Esiur.Stores.EntityCore
if (extension == null)
{
var store = Warehouse.New<EntityStore>(name, null, parent, manager, new { Options = optionsBuilder, DbContextProvider = dbContextProvider }).Wait();
//var store = Warehouse.New<EntityStore>(name, null, parent, manager, new { Options = optionsBuilder, DbContextProvider = dbContextProvider }).Wait();
store.Options = optionsBuilder.Options;
extension = new EsiurExtensionOptions(store);
//store.Options = optionsBuilder;
//store.DbContext = context;
}
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
@ -105,34 +167,34 @@ namespace Esiur.Stores.EntityCore
}
public static DbContextOptionsBuilder<TContext> UseEsiur<TContext>(
this DbContextOptionsBuilder<TContext> optionsBuilder,
//DbContext context,
string name = null,
IResource parent = null,
IPermissionsManager manager = null,
Func<DbContext> dbContextProvider = null)
where TContext : DbContext
{
//public static DbContextOptionsBuilder<TContext> UseEsiur<TContext>(
// this DbContextOptionsBuilder<TContext> optionsBuilder,
// //DbContext context,
// string name = null,
// IResource parent = null,
// IPermissionsManager manager = null,
// Func<DbContext> dbContextProvider = null)
// where TContext : DbContext
//{
var extension = optionsBuilder.Options.FindExtension<EsiurExtensionOptions>();
// var extension = optionsBuilder.Options.FindExtension<EsiurExtensionOptions>();
if (extension == null)
{
var store = Warehouse.New<EntityStore>(name, null, parent, manager, new { Options = optionsBuilder, DbContextProvider = dbContextProvider }).Wait();
extension = new EsiurExtensionOptions(store);
//store.Options = optionsBuilder;
//store.Options = extension;
//store.DbContext = context;
}
// if (extension == null)
// {
// var store = Warehouse.New<EntityStore>(name, null, parent, manager, new { Options = optionsBuilder, DbContextProvider = dbContextProvider }).Wait();
// extension = new EsiurExtensionOptions(store);
// //store.Options = optionsBuilder;
// //store.Options = extension;
// //store.DbContext = context;
// }
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
// ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
return optionsBuilder;
// return optionsBuilder;
}
//}
}
}

View File

@ -40,7 +40,7 @@ using Microsoft.EntityFrameworkCore.Metadata.Internal;
namespace Esiur.Stores.EntityCore
{
public class EsiurProxyRewrite : IModelFinalizingConvention
public class EsiurProxyRewrite : IModelFinalizingConvention
{
private static readonly MethodInfo _createInstance
= typeof(EsiurProxyRewrite).GetTypeInfo().GetDeclaredMethod(nameof(EsiurProxyRewrite.CreateInstance));
@ -79,7 +79,7 @@ namespace Esiur.Stores.EntityCore
var obj = Warehouse.New(entityType.ClrType).Wait() as EntityResource;//, "", options.Store, null, manager);
//obj._PrimaryId = id;
options.Store.TypesByType[entityType.ClrType].PrimaryKey.SetValue(obj, id);
Warehouse.Put(obj, id.ToString(), options.Store, null, null, 0, manager).Wait();
Warehouse.Put(id.ToString(), obj, options.Store, null, null, 0, manager).Wait();
// obj.Instance.IntVal = id;//.Variables.Add("eid", id);