public void ExtendModelAsync_UpdatesModel_IfHasOnModelCreatingMethod(Type type)
        {
            // Arrange
            var domain = Activator.CreateInstance(type);
            var extender = new ConventionalModelExtender(type);
            var domainConfig = new DomainConfiguration();
            domainConfig.EnsureCommitted();
            var domainContext = new DomainContext(domainConfig);
            domainContext.SetProperty(type.AssemblyQualifiedName, domain);
            var model = GetModel();
            var context = new ModelContext(domainContext) { Model = model };

            // Act
            extender.ExtendModelAsync(context, new CancellationToken());

            // Assert
            Assert.Same(model, context.Model);
            var operations = model.SchemaElements.OfType<IEdmOperation>();
            Assert.Single(operations);
            var operation = operations.Single();
            Assert.True(operation.IsBound);
            Assert.True(operation.IsFunction());
            Assert.Equal("MostExpensive", operation.Name);
            Assert.Equal("ns", operation.Namespace);
        }
 /// <inheritdoc/>
 public override void Initialize(
     DomainContext context,
     Type type,
     object instance)
 {
     Ensure.NotNull(context);
     Ensure.NotNull(type);
     context.SetProperty(type.AssemblyQualifiedName, instance);
 }
Exemplo n.º 3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EntityCollectionResult" /> class.
        /// </summary>
        /// <param name="query">The query that returns a collection of entities.</param>
        /// <param name="edmType">The EDM type reference of the entities.</param>
        /// <param name="context">The context where the action is executed.</param>
        public EntityCollectionResult(IQueryable query, IEdmTypeReference edmType, DomainContext context)
            : base(edmType)
        {
            Ensure.NotNull(query, "query");
            Ensure.NotNull(context, "context");

            this.Query = query;
            this.Context = context;
        }
Exemplo n.º 4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EntityResult" /> class.
        /// </summary>
        /// <param name="query">The query that returns an entity.</param>
        /// <param name="edmType">The EDM type reference of the entity.</param>
        /// <param name="context">The context where the action is executed.</param>
        public EntityResult(IQueryable query, IEdmTypeReference edmType, DomainContext context)
            : base(edmType)
        {
            Ensure.NotNull(query, "query");
            Ensure.NotNull(context, "context");

            this.Context = context;

            this.Result = query.SingleOrDefault();
        }
Exemplo n.º 5
0
        /// <summary>
        /// Asynchronously queries for data using a domain context.
        /// </summary>
        /// <param name="context">
        /// A domain context.
        /// </param>
        /// <param name="request">
        /// A query request.
        /// </param>
        /// <param name="cancellationToken">
        /// An optional cancellation token.
        /// </param>
        /// <returns>
        /// A task that represents the asynchronous
        /// operation whose result is a query result.
        /// </returns>
        public static async Task <QueryResult> QueryAsync(
            DomainContext context,
            QueryRequest request,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            Ensure.NotNull(context, "context");
            Ensure.NotNull(request, "request");
            var queryContext = new QueryContext(context, request);
            var model        = await Domain.GetModelAsync(context) as DomainModel;

            queryContext.Model = new DomainModel(queryContext, model.InnerModel);
            var handler = queryContext.GetHookPoint <IQueryHandler>();

            return(await handler.QueryAsync(queryContext, cancellationToken));
        }
Exemplo n.º 6
0
        /// <summary>
        /// Gets a queryable source of data using a domain context.
        /// </summary>
        /// <typeparam name="TElement">
        /// The type of the elements in the queryable source.
        /// </typeparam>
        /// <param name="context">
        /// A domain context.
        /// </param>
        /// <param name="name">
        /// The name of an entity set, singleton or composable function import.
        /// </param>
        /// <param name="arguments">
        /// If <paramref name="name"/> is a composable function import,
        /// the arguments to be passed to the composable function import.
        /// </param>
        /// <returns>
        /// A queryable source.
        /// </returns>
        /// <remarks>
        /// <para>
        /// If the name identifies a singleton or a composable function import
        /// whose result is a singleton, the resulting queryable source will
        /// be configured such that it represents exactly zero or one result.
        /// </para>
        /// <para>
        /// Note that the resulting queryable source cannot be synchronously
        /// enumerated, as the domain engine only operates asynchronously.
        /// </para>
        /// </remarks>
        public static IQueryable <TElement> Source <TElement>(
            DomainContext context,
            string name,
            params object[] arguments)
        {
            Ensure.NotNull(context, "context");
            Ensure.NotNull(name, "name");
            var elementType = Domain.EnsureElementType(context, null, name);

            if (typeof(TElement) != elementType)
            {
                // TODO GitHubIssue#24 : error message
                throw new ArgumentException();
            }

            return(Domain.SourceCore <TElement>(null, name, arguments));
        }
        /// <summary>
        /// Applies initialization routines from any domain participant
        /// attributes specified on a domain type to a domain context.
        /// </summary>
        /// <param name="type">
        /// A domain type.
        /// </param>
        /// <param name="instance">
        /// A domain instance, if applicable.
        /// </param>
        /// <param name="context">
        /// A domain context.
        /// </param>
        public static void ApplyInitialization(
            Type type, object instance, DomainContext context)
        {
            Ensure.NotNull(type, "type");
            Ensure.NotNull(context, "context");
            if (type.BaseType != null)
            {
                DomainParticipantAttribute.ApplyInitialization(
                    type.BaseType, instance, context);
            }

            var attributes = type.GetCustomAttributes(
                typeof(DomainParticipantAttribute), false);
            foreach (DomainParticipantAttribute attribute in attributes)
            {
                attribute.Initialize(context, type, instance);
            }
        }
        /// <summary>
        /// Applies initialization routines from any domain participant
        /// attributes specified on a domain type to a domain context.
        /// </summary>
        /// <param name="type">
        /// A domain type.
        /// </param>
        /// <param name="instance">
        /// A domain instance, if applicable.
        /// </param>
        /// <param name="context">
        /// A domain context.
        /// </param>
        public static void ApplyInitialization(
            Type type, object instance, DomainContext context)
        {
            Ensure.NotNull(type, "type");
            Ensure.NotNull(context, "context");
            if (type.BaseType != null)
            {
                DomainParticipantAttribute.ApplyInitialization(
                    type.BaseType, instance, context);
            }

            var attributes = type.GetCustomAttributes(
                typeof(DomainParticipantAttribute), false);

            foreach (DomainParticipantAttribute attribute in attributes)
            {
                attribute.Initialize(context, type, instance);
            }
        }
        /// <summary>
        /// Applies disposal routines from any domain participant
        /// attributes specified on a domain type to a domain context.
        /// </summary>
        /// <param name="type">
        /// A domain type.
        /// </param>
        /// <param name="instance">
        /// A domain instance, if applicable.
        /// </param>
        /// <param name="context">
        /// A domain context.
        /// </param>
        public static void ApplyDisposal(
            Type type, object instance, DomainContext context)
        {
            Ensure.NotNull(type, "type");
            Ensure.NotNull(context, "context");
            var attributes = type.GetCustomAttributes(
                typeof(DomainParticipantAttribute), false);

            foreach (DomainParticipantAttribute attribute in attributes.Reverse())
            {
                attribute.Dispose(context, type, instance);
            }

            if (type.BaseType != null)
            {
                DomainParticipantAttribute.ApplyDisposal(
                    type.BaseType, instance, context);
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// Tries to get the relevant type of an entity
        /// set, singleton, or composable function import.
        /// </summary>
        /// <param name="context">
        /// A domain context.
        /// </param>
        /// <param name="name">
        /// The name of an entity set, singleton or composable function import.
        /// </param>
        /// <param name="relevantType">
        /// When this method returns, provides the
        /// relevant type of the queryable source.
        /// </param>
        /// <returns>
        /// <c>true</c> if the relevant type was
        /// provided; otherwise, <c>false</c>.
        /// </returns>
        public bool TryGetRelevantType(
            DomainContext context,
            string name,
            out Type relevantType)
        {
            // TODO GitHubIssue#39 : support something beyond entity sets
            relevantType = null;
            var property = this.dbContextType.GetProperty(name);
            if (property != null)
            {
                var type = property.PropertyType;
                if (type.IsGenericType &&
                    type.GetGenericTypeDefinition() == typeof(DbSet<>))
                {
                    relevantType = type.GetGenericArguments()[0];
                }
            }

            return relevantType != null;
        }
        public void ExtendModelAsync_DoesntUpdatesModel_IfWithoutOnModelCreatingMethod()
        {
            // Arrange
            var domain = new AnyDomain();
            var type = domain.GetType();
            var extender = new ConventionalModelExtender(type);
            var domainConfig = new DomainConfiguration();
            domainConfig.EnsureCommitted();
            var domainContext = new DomainContext(domainConfig);
            domainContext.SetProperty(type.AssemblyQualifiedName, domain);
            var model = GetModel();
            var context = new ModelContext(domainContext) { Model = model };

            // Act
            extender.ExtendModelAsync(context, new CancellationToken());

            // Assert
            Assert.Same(model, context.Model);
            Assert.Empty(model.SchemaElements.OfType<IEdmOperation>());
        }
Exemplo n.º 12
0
        /// <summary>
        /// Tries to get the relevant type of an entity
        /// set, singleton, or composable function import.
        /// </summary>
        /// <param name="context">
        /// A domain context.
        /// </param>
        /// <param name="name">
        /// The name of an entity set, singleton or composable function import.
        /// </param>
        /// <param name="relevantType">
        /// When this method returns, provides the
        /// relevant type of the queryable source.
        /// </param>
        /// <returns>
        /// <c>true</c> if the relevant type was
        /// provided; otherwise, <c>false</c>.
        /// </returns>
        public virtual bool TryGetRelevantType(
            DomainContext context,
            string name,
            out Type relevantType)
        {
            // TODO GitHubIssue#39 : support something beyond entity sets
            relevantType = null;
            var property = this.dbContextType.GetProperty(name);
            if (property != null)
            {
                var type = property.PropertyType;
                var genericType = type.FindGenericType(typeof (IDbSet<>));
                if (genericType != null)
                {
                    relevantType = genericType.GetGenericArguments()[0];
                }
            }

            return relevantType != null;
        }
Exemplo n.º 13
0
        /// <summary>
        /// Asynchronously gets a domain model using a domain context.
        /// </summary>
        /// <param name="context">
        /// A domain context.
        /// </param>
        /// <param name="cancellationToken">
        /// An optional cancellation token.
        /// </param>
        /// <returns>
        /// A task that represents the asynchronous
        /// operation whose result is the domain model.
        /// </returns>
        public static async Task <IEdmModel> GetModelAsync(
            DomainContext context,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            Ensure.NotNull(context, "context");
            var configuration = context.Configuration;
            var model         = configuration.Model;

            if (model == null)
            {
                var modelContext = new ModelContext(context);
                var handler      = modelContext.GetHookPoint <IModelHandler>();
                var result       = await handler.GetModelAsync(
                    modelContext, cancellationToken);

                configuration.Model = new DomainModel(configuration, result);
                model = configuration.Model;
            }

            return(model);
        }
        /// <summary>
        /// Applies disposal routines from any domain participant
        /// attributes specified on a domain type to a domain context.
        /// </summary>
        /// <param name="type">
        /// A domain type.
        /// </param>
        /// <param name="instance">
        /// A domain instance, if applicable.
        /// </param>
        /// <param name="context">
        /// A domain context.
        /// </param>
        public static void ApplyDisposal(
            Type type, object instance, DomainContext context)
        {
            Ensure.NotNull(type, "type");
            Ensure.NotNull(context, "context");
            var attributes = type.GetCustomAttributes(
                typeof(DomainParticipantAttribute), false);
            foreach (DomainParticipantAttribute attribute in attributes.Reverse())
            {
                attribute.Dispose(context, type, instance);
            }

            if (type.BaseType != null)
            {
                DomainParticipantAttribute.ApplyDisposal(
                    type.BaseType, instance, context);
            }
        }
Exemplo n.º 15
0
        void IExpandableDomain.Initialize(
            DomainConfiguration derivedConfiguration)
        {
            if (this.IsDisposed)
            {
                throw new ObjectDisposedException(this.GetType().FullName);
            }

            if (this.domainContext != null)
            {
                throw new InvalidOperationException();
            }

            Ensure.NotNull(derivedConfiguration, "derivedConfiguration");
            var baseConfiguration = this.DomainConfiguration;
            var candidate = derivedConfiguration;
            while (candidate != baseConfiguration)
            {
                if (candidate.BaseConfiguration == null)
                {
                    // TODO GitHubIssue#24 : error message
                    throw new ArgumentException();
                }

                candidate = candidate.BaseConfiguration;
            }

            this.domainConfiguration = derivedConfiguration;
            this.domainContext = this.CreateDomainContext(derivedConfiguration);
            DomainParticipantAttribute.ApplyInitialization(
                this.GetType(), this, this.domainContext);
        }
Exemplo n.º 16
0
 /// <summary>
 /// Disposes a domain context.
 /// </summary>
 /// <param name="context">
 /// A domain context.
 /// </param>
 /// <param name="type">
 /// The domain type on which this attribute was placed.
 /// </param>
 /// <param name="instance">
 /// A domain instance, if applicable.
 /// </param>
 public virtual void Dispose(
     DomainContext context,
     Type type,
     object instance)
 {
 }
Exemplo n.º 17
0
 /// <summary>
 /// Initializes a new instance of the <see cref="InvocationContext" /> class.
 /// </summary>
 /// <param name="domainContext">
 /// A domain context.
 /// </param>
 public InvocationContext(DomainContext domainContext)
 {
     Ensure.NotNull(domainContext, "domainContext");
     this.DomainContext = domainContext;
 }
Exemplo n.º 18
0
 /// <summary>
 /// Initializes a domain context.
 /// </summary>
 /// <param name="context">
 /// A domain context.
 /// </param>
 /// <param name="type">
 /// The domain type on which this attribute was placed.
 /// </param>
 /// <param name="instance">
 /// A domain instance, if applicable.
 /// </param>
 public virtual void Initialize(
     DomainContext context,
     Type type,
     object instance)
 {
 }
Exemplo n.º 19
0
 /// <summary>
 /// Tries to get the relevant type of a composable function.
 /// </summary>
 /// <param name="context">
 /// A domain context.
 /// </param>
 /// <param name="namespaceName">
 /// The name of a namespace containing a composable function.
 /// </param>
 /// <param name="name">
 /// The name of composable function.
 /// </param>
 /// <param name="relevantType">
 /// When this method returns, provides the
 /// relevant type of the composable function.
 /// </param>
 /// <returns>
 /// <c>true</c> if the relevant type was
 /// provided; otherwise, <c>false</c>.
 /// </returns>
 public bool TryGetRelevantType(
     DomainContext context,
     string namespaceName,
     string name,
     out Type relevantType)
 {
     // TODO GitHubIssue#39 : support composable function imports
     relevantType = null;
     return false;
 }
 /// <inheritdoc/>
 public bool TryGetRelevantType(
     DomainContext context,
     string namespaceName,
     string name,
     out Type relevantType)
 {
     relevantType = null;
     return false;
 }
        /// <inheritdoc/>
        public bool TryGetRelevantType(
            DomainContext context,
            string name,
            out Type relevantType)
        {
            relevantType = null;
            var entitySetProperty = this.AddedEntitySets
                .SingleOrDefault(p => p.Name == name);
            if (entitySetProperty != null)
            {
                relevantType = entitySetProperty
                    .PropertyType.GetGenericArguments()[0];
            }

            return relevantType != null;
        }
 /// <summary>
 /// Disposes a domain context.
 /// </summary>
 /// <param name="context">
 /// A domain context.
 /// </param>
 /// <param name="type">
 /// The domain type on which this attribute was placed.
 /// </param>
 /// <param name="instance">
 /// A domain instance, if applicable.
 /// </param>
 public virtual void Dispose(
     DomainContext context,
     Type type,
     object instance)
 {
 }
Exemplo n.º 23
0
 /// <summary>
 /// Releases the unmanaged resources that are used by the
 /// object and, optionally, releases the managed resources.
 /// </summary>
 /// <param name="disposing">
 /// <c>true</c> to release both managed and unmanaged resources;
 /// <c>false</c> to release only unmanaged resources.
 /// </param>
 protected virtual void Dispose(bool disposing)
 {
     if (disposing)
     {
         this.domainContext = null;
         this.IsDisposed = true;
     }
 }
 /// <summary>
 /// Initializes a domain context.
 /// </summary>
 /// <param name="context">
 /// A domain context.
 /// </param>
 /// <param name="type">
 /// The domain type on which this attribute was placed.
 /// </param>
 /// <param name="instance">
 /// A domain instance, if applicable.
 /// </param>
 public virtual void Initialize(
     DomainContext context,
     Type type,
     object instance)
 {
 }