private static void InterceptContext(IInterceptable interceptable, ContextAccessor <TDbContext> accessor) { var nameDescriptor = InterceptionDescriptor.InterceptMethod("OnModelCreating"); nameDescriptor.ParameterTypes = new[] { typeof(ModelBuilder) }; nameDescriptor.PostAction = (s, v) => { if (!accessor.DataOptions.Access.AutomaticMapping) { return; } var modelBuilder = v.Parameters?[0]?.As <ModelBuilder>() !; // 默认尝试创建迁移程序集的模型 if (!string.IsNullOrEmpty(accessor.RelationalExtension?.MigrationsAssembly)) { modelBuilder.CreateAssembliesModels(accessor.RelationalExtension.MigrationsAssembly); } // 启用对实体加密属性功能的支持 var converterFactory = accessor.OriginalContext.GetService <IEncryptionConverterFactory>(); foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { entityType.UseEncryption(converterFactory, accessor); entityType.UseQueryFilters(accessor.DataOptions.QueryFilters, accessor); accessor.ModelCreatedAction?.Invoke(entityType, accessor); } }; }
internal static void AddInterceptorImpl <T>(this IInterceptable <T> interceptable, T interceptor) where T : IInterceptor { if (interceptable.Interceptor == null) { interceptable.Interceptor = interceptor; } else if (interceptable.Interceptor is AggregatedInterceptor <T> aggregated) { aggregated.Interceptors.Add(interceptor); } else { switch (interceptable) { case IInterceptable <ICommandInterceptor> cmi when interceptor is ICommandInterceptor cm: cmi.Interceptor = new AggregatedCommandInterceptor { Interceptors = { cmi.Interceptor !, cm } }; break; case IInterceptable <IConnectionInterceptor> ci when interceptor is IConnectionInterceptor c: ci.Interceptor = new AggregatedConnectionInterceptor { Interceptors = { ci.Interceptor !, c } }; break; case IInterceptable <IDataContextInterceptor> dci when interceptor is IDataContextInterceptor dc: dci.Interceptor = new AggregatedDataContextInterceptor { Interceptors = { dci.Interceptor !, dc } }; break; case IInterceptable <IEntityServiceInterceptor> esi when interceptor is IEntityServiceInterceptor es: esi.Interceptor = new AggregatedEntityServiceInterceptor { Interceptors = { esi.Interceptor !, es } }; break; case IInterceptable <IUnwrapDataObjectInterceptor> wri when interceptor is IUnwrapDataObjectInterceptor wr: wri.Interceptor = new AggregatedUnwrapDataObjectInterceptor { Interceptors = { wri.Interceptor !, wr } }; break; default: throw new NotImplementedException($"AddInterceptor for '{typeof(T).Name}' is not implemented."); } } }
internal static void AddInterceptorImpl(this IInterceptable interceptable, IInterceptor interceptor) { switch (interceptor) { case ICommandInterceptor cm: AddInterceptorImpl((IInterceptable <ICommandInterceptor>)interceptable, cm); break; case IConnectionInterceptor cn: AddInterceptorImpl((IInterceptable <IConnectionInterceptor>)interceptable, cn); break; case IDataContextInterceptor dc: AddInterceptorImpl((IInterceptable <IDataContextInterceptor>)interceptable, dc); break; case IEntityServiceInterceptor es: AddInterceptorImpl((IInterceptable <IEntityServiceInterceptor>)interceptable, es); break; case IUnwrapDataObjectInterceptor wr: AddInterceptorImpl((IInterceptable <IUnwrapDataObjectInterceptor>)interceptable, wr); break; } }
internal static void RemoveInterceptor <T>(this IInterceptable <T> interceptable, IInterceptor interceptor) where T : IInterceptor { if (interceptor is T i) { switch (interceptable.Interceptor) { case null: break; case AggregatedInterceptor <T> ae: ae.Remove(i); break; case IInterceptor e when e == interceptor: interceptable.Interceptor = default; break; } } }
public static T NotifyInterceptors <T>(this IInterceptable <T> interceptable, T change) { var tracked = States.UntrackedStart(); try { var interceptors = interceptable.Interceptors.ToList(); foreach (var interceptor in interceptors) { change = interceptor(change); if (change == null) { break; } } return(change); } finally { States.UntrackedEnd(tracked); } }
public InterceptableList(IInterceptable interceptable, string propertyName) : this() { Interceptable = interceptable; PropertyName = propertyName; }
public HomeController(IInterceptable <ISystemClock> clockAccessor) { _clock = clockAccessor.Proxy; Debug.Assert(typeof(SystemClock) != _clock.GetType()); }
//[DebuggerStepThrough()] protected virtual void DoNotifyPropertySet(object obj, string propertyName, ref object value, object oldValue, bool hasOldValue, ref bool cancel) { IContext ctx = this.Context; IObjectManager om = ctx.ObjectManager; IPersistenceEngine pe = ctx.PersistenceEngine; PropertyCancelEventArgs e; if (hasOldValue) { e = new PropertyCancelEventArgs(obj, propertyName, value, oldValue, this.Context.ObjectManager.GetNullValueStatus(obj, propertyName)); } else { e = new PropertyCancelEventArgs(obj, propertyName, value, this.Context.ObjectManager.GetPropertyValue(obj, propertyName), this.Context.ObjectManager.GetNullValueStatus(obj, propertyName)); } this.Context.EventManager.OnWritingProperty(this, e); if (e.Cancel) { cancel = true; return; } value = e.NewValue; IClassMap classMap = ctx.DomainMap.MustGetClassMap(obj.GetType()); IPropertyMap propertyMap; string prevId; string newId; propertyMap = classMap.MustGetPropertyMap(propertyName); if (propertyMap.ReferenceType != ReferenceType.None && value != null) { if (propertyMap.ReferenceType == ReferenceType.OneToMany || propertyMap.ReferenceType == ReferenceType.OneToOne) { //parent object IInterceptable ivalue = value as IInterceptable; if (ivalue == null) { throw new NPersistException(string.Format("Object is not a NPersist managed object, do not use 'new' on Entities. (Property='{0}', Owner={1})", propertyName, obj)); } else { if (ivalue.GetInterceptor().Context != this.Context) { throw new NPersistException(string.Format("Object does not belong to the same context object as the property owner. (Property='{0}', Owner={1})", propertyName, obj)); } ObjectStatus valueObjectStatus = om.GetObjectStatus(value); if (valueObjectStatus == ObjectStatus.UpForDeletion || valueObjectStatus == ObjectStatus.Deleted) { throw new DeletedObjectException(string.Format("Object has been deleted. (Object={0})", value), value); } } } else if (propertyMap.ReferenceType == ReferenceType.ManyToOne || propertyMap.ReferenceType == ReferenceType.ManyToMany) { IInterceptableList ivalue = value as IInterceptableList; if (ivalue == null) { throw new NPersistException(string.Format("List is not a NPersist managed list, do not use 'new' to initialize lists, NPersist does this for you. (Property='{0}', Owner={1})", propertyName, obj)); } else if (ivalue.Interceptable.GetInterceptor().Context != this.Context) { throw new NPersistException(string.Format("List does not belong to the same context object as the property owner. (Property='{0}', Owner={1})", propertyName, obj)); } } } if (propertyMap.IsReadOnly) { //Let read-only inverse properties through if (!(propertyMap.ReferenceType != ReferenceType.None && propertyMap.Inverse.Length > 0 && propertyMap.NoInverseManagement == false)) { //Special - if someone forgot to make their ManyOne read-only, //why bug them about it? (so don't add an "else" with an exception...) if (propertyMap.ReferenceType != ReferenceType.ManyToOne) { throw new ReadOnlyException("Property '" + classMap.Name + "." + propertyName + "' is read-only!"); // do not localize } } } PropertyStatus propStatus = PropertyStatus.Clean; ObjectStatus objStatus = om.GetObjectStatus(obj); bool hasPropertyStatus = false; if (objStatus == ObjectStatus.Deleted) { throw new DeletedObjectException("The object has been deleted!", obj, propertyName); // do not localize } else if (objStatus == ObjectStatus.UpForDeletion) { throw new DeletedObjectException("The object has been registered as up for deletion!", obj, propertyName); // do not localize } this.Context.ObjectCloner.EnsureIsClonedIfEditing(obj); if (objStatus == ObjectStatus.UpForCreation) { } else if (objStatus == ObjectStatus.Clean) { propStatus = om.GetPropertyStatus(obj, propertyName); if (propStatus == PropertyStatus.NotLoaded) { pe.LoadProperty(obj, propertyName); } if (!(hasOldValue)) { if (!(om.ComparePropertyValues(obj, propertyName, value, om.GetPropertyValue(obj, propertyName)))) { this.Context.UnitOfWork.RegisterDirty(obj); } } } else if (objStatus == ObjectStatus.NotLoaded) { propertyMap = this.Context.DomainMap.MustGetClassMap(obj.GetType()).MustGetPropertyMap(propertyName); if (!(propertyMap.IsIdentity)) { propStatus = this.Context.ObjectManager.GetPropertyStatus(obj, propertyName); hasPropertyStatus = true; //it would be sweet to be able to determine beforehand if this property would be part of the span //that is loaded with LoadObject and only call LoadObject if that is the case.... if (propStatus == PropertyStatus.NotLoaded) { hasPropertyStatus = false; //this.Context.PersistenceEngine.LoadObject(ref obj); this.Context.IdentityMap.LoadObject(ref obj, true); if (obj == null) { throw new ObjectNotFoundException("Object not found!"); // do not localize } } if (!hasPropertyStatus) { propStatus = om.GetPropertyStatus(obj, propertyName); } if (propStatus == PropertyStatus.NotLoaded) { pe.LoadProperty(obj, propertyName); } } if (!(hasOldValue)) { if (!(om.ComparePropertyValues(obj, propertyName, value, om.GetPropertyValue(obj, propertyName)))) { this.Context.UnitOfWork.RegisterDirty(obj); } } } else if (objStatus == ObjectStatus.Dirty) { propStatus = om.GetPropertyStatus(obj, propertyName); if (propStatus == PropertyStatus.NotLoaded) { pe.LoadProperty(obj, propertyName); } } if (propertyMap.IsIdentity) { prevId = om.GetObjectIdentity(obj); newId = om.GetObjectIdentity(obj, propertyMap, value); if (prevId != newId) { ctx.IdentityMap.UpdateIdentity(obj, prevId, newId); } } om.SetNullValueStatus(obj, propertyName, false); om.SetUpdatedStatus(obj, propertyName, true); if (hasOldValue) { ctx.InverseManager.NotifyPropertySet(obj, propertyName, value, oldValue); ctx.UnitOfWork.RegisterDirty(obj); } else { ctx.InverseManager.NotifyPropertySet(obj, propertyName, value); } }
public HomeController(IInterceptable <ISystomClock> interceptable) { _clock = interceptable.Proxy; }
public HomeController(IInterceptable <ISystemClock> clockAccessor) { _clock = clockAccessor.Proxy; }
public HomeController(IInterceptable <IFoobarService> service) { _service = service.Proxy; }
public static bool HasInterceptors <T>(this IInterceptable <T> interceptable) { return(interceptable.Interceptors.Count > 0); }
public static IDisposable ResigerInterceptor <T>(this IInterceptable <T> interceptable, Func <T, T> interceptor) { interceptable.Interceptors.Add(interceptor); return(new Disposable(() => interceptable.Interceptors.Remove(interceptor))); }