Ejemplo n.º 1
0
    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);
            }
        };
    }
Ejemplo n.º 2
0
        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.");
                }
            }
        }
Ejemplo n.º 3
0
        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;
            }
        }
Ejemplo n.º 4
0
        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;
 }
Ejemplo n.º 7
0
 public HomeController(IInterceptable <ISystemClock> clockAccessor)
 {
     _clock = clockAccessor.Proxy;
     Debug.Assert(typeof(SystemClock) != _clock.GetType());
 }
Ejemplo n.º 8
0
        //[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);
            }
        }
Ejemplo n.º 9
0
 public HomeController(IInterceptable <ISystomClock> interceptable)
 {
     _clock = interceptable.Proxy;
 }
Ejemplo n.º 10
0
 public HomeController(IInterceptable <ISystemClock> clockAccessor)
 {
     _clock = clockAccessor.Proxy;
 }
Ejemplo n.º 11
0
 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)));
        }
Ejemplo n.º 14
0
 public InterceptableList(IInterceptable interceptable, string propertyName) : this()
 {
     Interceptable = interceptable;
     PropertyName  = propertyName;
 }