public DomainService CreateDomainService(Type domainServiceType, DomainServiceContext context) { var service = Global.UnityContainer.Resolve(domainServiceType) as DomainService; service.Initialize(context); return(service); }
/// <summary> /// Helper method performs a query operation against a given proxy instance. /// </summary> /// <param name="domainService">The type of <see cref="DomainService"/> to perform this query operation against.</param> /// <param name="context">The current context.</param> /// <param name="domainServiceInstances">The list of tracked <see cref="DomainService"/> instances that any newly created /// <see cref="DomainServices"/> will be added to.</param> /// <param name="queryName">The name of the query to invoke.</param> /// <param name="parameters">The query parameters.</param> /// <returns>The query results. May be null if there are no query results.</returns> /// <exception cref="ArgumentNullException">if <paramref name="context"/> is null.</exception> /// <exception cref="ArgumentNullException">if <paramref name="queryName"/> is null or an empty string.</exception> /// <exception cref="InvalidOperationException">if no match query operation exists on the <paramref name="context"/>.</exception> /// <exception cref="OperationException">if operation errors are thrown during execution of the query operation.</exception> public static IEnumerable Query(Type domainService, DomainServiceContext context, IList <DomainService> domainServiceInstances, string queryName, object[] parameters) { context = new DomainServiceContext(context, DomainOperationType.Query); DomainService service = CreateDomainServiceInstance(domainService, context, domainServiceInstances); DomainServiceDescription serviceDescription = DomainServiceDescription.GetDescription(service.GetType()); DomainOperationEntry queryOperation = serviceDescription.GetQueryMethod(queryName); if (queryOperation == null) { string errorMessage = string.Format( CultureInfo.InvariantCulture, Resource.DomainServiceProxy_QueryOperationNotFound, queryName, domainService); throw new InvalidOperationException(errorMessage); } object[] parameterValues = parameters ?? Array.Empty <object>(); QueryDescription queryDescription = new QueryDescription(queryOperation, parameterValues); var actualMethod = s_queryGeneric.MakeGenericMethod(queryDescription.Method.AssociatedType); try { return((IEnumerable)actualMethod.Invoke(null, new object[] { service, queryDescription })); } catch (TargetInvocationException tie) when(tie.InnerException is object) { throw tie.InnerException; } }
/// <summary> /// Helper method performs a query operation against a given proxy instance. /// </summary> /// <param name="domainService">The type of <see cref="DomainService"/> to perform this query operation against.</param> /// <param name="context">The current context.</param> /// <param name="domainServiceInstances">The list of tracked <see cref="DomainService"/> instances that any newly created /// <see cref="DomainServices"/> will be added to.</param> /// <param name="queryName">The name of the query to invoke.</param> /// <param name="parameters">The query parameters.</param> /// <returns>The query results. May be null if there are no query results.</returns> /// <exception cref="ArgumentNullException">if <paramref name="context"/> is null.</exception> /// <exception cref="ArgumentNullException">if <paramref name="queryName"/> is null or an empty string.</exception> /// <exception cref="InvalidOperationException">if no match query operation exists on the <paramref name="context"/>.</exception> /// <exception cref="OperationException">if operation errors are thrown during execution of the query operation.</exception> public static IEnumerable Query(Type domainService, DomainServiceContext context, IList <DomainService> domainServiceInstances, string queryName, object[] parameters) { context = new DomainServiceContext(context, DomainOperationType.Query); DomainService service = CreateDomainServiceInstance(domainService, context, domainServiceInstances); DomainServiceDescription serviceDescription = DomainServiceDescription.GetDescription(service.GetType()); DomainOperationEntry queryOperation = serviceDescription.GetQueryMethod(queryName); if (queryOperation == null) { string errorMessage = string.Format( CultureInfo.InvariantCulture, Resource.DomainServiceProxy_QueryOperationNotFound, queryName, domainService); throw new InvalidOperationException(errorMessage); } int totalCount; IEnumerable <ValidationResult> validationErrors; object[] parameterValues = parameters ?? new object[0]; QueryDescription queryDescription = new QueryDescription(queryOperation, parameterValues); IEnumerable result = service.Query(queryDescription, out validationErrors, out totalCount); if (validationErrors != null && validationErrors.Any()) { IEnumerable <ValidationResultInfo> operationErrors = validationErrors.Select(ve => new ValidationResultInfo(ve.ErrorMessage, ve.MemberNames)); throw new OperationException(Resource.DomainServiceProxy_OperationError, operationErrors); } return(result); }
public async Task DomainService_DirectQuery() { DomainServiceDescription description = DomainServiceDescription.GetDescription(typeof(TestDomainServices.EF.Catalog)); TestDomainServices.EF.Catalog service = new TestDomainServices.EF.Catalog(); DomainServiceContext dsc = new DomainServiceContext(new MockDataService(new MockUser("mathew") { IsAuthenticated = true }), DomainOperationType.Query); service.Initialize(dsc); DomainOperationEntry queryOperation = description.GetQueryMethod("GetPurchaseOrders"); ServiceQuery serviceQuery = new ServiceQuery(); serviceQuery.QueryParts = new ServiceQueryPart[] { new ServiceQueryPart("where", "(it.Freight!=0)"), new ServiceQueryPart("take", "1") }; QueryResult <AdventureWorksModel.PurchaseOrder> result = await QueryProcessor.ProcessAsync <AdventureWorksModel.PurchaseOrder>(service, queryOperation, Array.Empty <object>(), serviceQuery); Assert.AreEqual(1, result.RootResults.Count()); }
/// <summary> /// Creates a <see cref="DomainService"/> instance for a given <see cref="DomainServiceContext"/>. /// </summary> /// <param name="domainService">The <see cref="DomainService"/> <see cref="Type"/> to create.</param> /// <param name="context">The <see cref="DomainServiceContext"/> to provide to the <see cref="DomainService.Factory"/>.</param> /// <param name="domainServiceInstances">The list used to track <see cref="DomainService"/> instances.</param> /// <returns>A <see cref="DomainService"/> instance.</returns> private static DomainService CreateDomainServiceInstance(Type domainService, DomainServiceContext context, IList <DomainService> domainServiceInstances) { DomainService service = DomainService.Factory.CreateDomainService(domainService, context); domainServiceInstances.Add(service); return(service); }
public async Task TestDirectChangeset_Simple() { for (int i = 0; i < 100; i++) { TestDomainServices.TestProvider_Scenarios ds = new TestDomainServices.TestProvider_Scenarios(); DomainServiceContext dsc = new DomainServiceContext(new MockDataService(new MockUser("mathew")), DomainOperationType.Submit); ds.Initialize(dsc); List <ChangeSetEntry> entries = new List <ChangeSetEntry>(); for (int j = 0; j < 500; j++) { TestDomainServices.POCONoValidation e = new TestDomainServices.POCONoValidation() { ID = i, A = "A" + i, B = "B" + i, C = "C" + i, D = "D" + i, E = "E" + i }; entries.Add(new ChangeSetEntry(j, e, null, DomainOperation.Insert)); } await ChangeSetProcessor.ProcessAsync(ds, entries); Assert.IsFalse(entries.Any(p => p.HasError)); } }
private DomainService GetDomainService(object instance) { // create and initialize the DomainService for this request DomainServiceBehavior.DomainServiceInstanceInfo instanceInfo = (DomainServiceBehavior.DomainServiceInstanceInfo)instance; IServiceProvider serviceProvider = (IServiceProvider)OperationContext.Current.Host; DomainServiceContext context = new DomainServiceContext(serviceProvider, this.operationType); try { DomainService domainService = DomainService.Factory.CreateDomainService(instanceInfo.DomainServiceType, context); instanceInfo.DomainServiceInstance = domainService; return(domainService); } catch (TargetInvocationException tie) { if (tie.InnerException != null) { throw ServiceUtility.CreateFaultException(tie.InnerException); } throw ServiceUtility.CreateFaultException(tie); } catch (Exception ex) { if (ex.IsFatal()) { throw; } throw ServiceUtility.CreateFaultException(ex); } }
public void DomainService_DirectQuery() { DomainServiceDescription description = DomainServiceDescription.GetDescription(typeof(TestDomainServices.EF.Catalog)); TestDomainServices.EF.Catalog service = new TestDomainServices.EF.Catalog(); DomainServiceContext dsc = new DomainServiceContext(new MockDataService(new MockUser("mathew") { IsAuthenticated = true }), DomainOperationType.Query); service.Initialize(dsc); DomainOperationEntry queryOperation = description.GetQueryMethod("GetPurchaseOrders"); ServiceQuery serviceQuery = new ServiceQuery(); serviceQuery.QueryParts = new ServiceQueryPart[] { new ServiceQueryPart("where", "(it.Freight!=0)"), new ServiceQueryPart("take", "1") }; IEnumerable <ValidationResult> validationErrors; int totalCount; QueryResult <AdventureWorksModel.PurchaseOrder> result = QueryProcessor.Process <AdventureWorksModel.PurchaseOrder>(service, queryOperation, new object[0], serviceQuery, out validationErrors, out totalCount); Assert.AreEqual(1, result.RootResults.Count()); }
public DomainService CreateDomainService(Type domainServiceType, DomainServiceContext context) { AdventureWorksDataContext ctxt = new AdventureWorksDataContext(); IRepository <Employee> empRepository = new LinqToSqlRepository <Employee>(ctxt); DomainService ds = (DomainService)Activator.CreateInstance(domainServiceType, new object[] { empRepository }); ds.Initialize(context); return(ds); }
/// <summary> /// Creates a <typeparamref name="TDomainService"/> proxy instance that implements /// <typeparamref name="TDomainServiceContract"/>. /// </summary> /// <typeparam name="TDomainServiceContract">The <see cref="DomainService"/> contract interface.</typeparam> /// <typeparam name="TDomainService">The <see cref="DomainService"/> type that implements <typeparamref name="TDomainServiceContract"/>.</typeparam> /// <param name="httpContext">The <see cref="HttpContextBase"/> instance that should be provided to <typeparamref name="TDomainService"/> /// proxy instances.</param> /// <returns>Returns a <typeparamref name="TDomainService"/> proxy instance that implements /// <typeparamref name="TDomainServiceContract"/>.</returns> public static TDomainServiceContract Create <TDomainServiceContract, TDomainService>(HttpContextBase httpContext) where TDomainServiceContract : IDisposable where TDomainService : DomainService { // Create a DomainServiceContext (with access to the provided HttpContextBase) and use that as our context HttpContextBaseServiceProvider serviceProvider = new HttpContextBaseServiceProvider(httpContext); DomainServiceContext context = new DomainServiceContext(serviceProvider, DomainOperationType.Query); return(DomainServiceProxy.Create <TDomainServiceContract, TDomainService>(context)); }
/// <summary> /// Handles the creation of domain service objects. /// </summary> public DomainService CreateDomainService(Type domainServiceType, DomainServiceContext context) { var domainService = (DomainService)IoC.GetByType(domainServiceType); if (domainService != null) { domainService.Initialize(context); } return(domainService); }
public DomainService CreateDomainService(Type domainServiceType, DomainServiceContext context) { if (domainServiceType != typeof(TDomainService)) { throw new InvalidOperationException("Only DomainServices of type '{0}' can be instantiated with this factory."); } TDomainService domainService = this._createDomainService(); domainService.Initialize(context); return(domainService); }
public DomainService CreateDomainService(Type domainServiceType, DomainServiceContext context) { DomainService service = null; if (domainServiceType == typeof(EmployeeDomainService)) service = new EmployeeDomainService(new EmployeeRepositoryInMemory()); else service = (DomainService)Activator.CreateInstance(domainServiceType, true); service.Initialize(context); return service; }
/// <summary> /// Initialize the <see cref="DomainService"/>, setting the /// <see cref="ValidationContext"/> with custom state and services. /// </summary> /// <param name="context"> /// Represents the execution environment for the operations performed /// by a System.ServiceModel.DomainServices.Server.DomainService. /// </param> public override void Initialize(DomainServiceContext context) { var contextItems = new Dictionary <object, object> { { "AllowOverBooking", HttpContext.Current.Session["AllowOverBooking"] ?? false } }; this.ValidationContext = new ValidationContext(this, context, contextItems); this.ValidationContext.ServiceContainer.AddService(typeof(IMeetingDataProvider), this); base.Initialize(context); }
public DomainService CreateDomainService(Type domainServiceType, DomainServiceContext context) { DomainService ds = ... // code to create a service, or look it up // from a container if (ds != null) { ds.Initialize(context); } return(ds); }
public void DomainService_InvalidOperationType() { TestDomainServices.EF.Northwind nw = new TestDomainServices.EF.Northwind(); DomainServiceContext dsc = new DomainServiceContext(new MockDataService(new MockUser("mathew") { IsAuthenticated = true }), DomainOperationType.Submit); nw.Initialize(dsc); IEnumerable <ValidationResult> validationResults = null; int totalCount; DomainServiceDescription dsd = DomainServiceDescription.GetDescription(typeof(TestDomainServices.EF.Northwind)); DomainOperationEntry entry = dsd.DomainOperationEntries.First(p => p.Operation == DomainOperation.Query); QueryDescription qd = new QueryDescription(entry); ExceptionHelper.ExpectException <InvalidOperationException>(delegate { nw.Query(qd, out validationResults, out totalCount); }, string.Format(Resource.DomainService_InvalidOperationType, DomainOperationType.Submit, DomainOperationType.Query)); InvokeDescription id = new InvokeDescription(entry, null); ExceptionHelper.ExpectException <InvalidOperationException>(delegate { nw.Invoke(id, out validationResults); }, string.Format(Resource.DomainService_InvalidOperationType, DomainOperationType.Submit, DomainOperationType.Invoke)); nw = new TestDomainServices.EF.Northwind(); dsc = new DomainServiceContext(new MockDataService(new MockUser("mathew") { IsAuthenticated = true }), DomainOperationType.Query); nw.Initialize(dsc); ChangeSet cs = new ChangeSet(new ChangeSetEntry[] { new ChangeSetEntry() { Entity = new ServiceContext_CurrentOperation_Entity() { Key = 1 }, Operation = DomainOperation.Insert } }); ExceptionHelper.ExpectException <InvalidOperationException>(delegate { nw.Submit(cs); }, string.Format(Resource.DomainService_InvalidOperationType, DomainOperationType.Query, DomainOperationType.Submit)); }
/// <summary> /// Creates an <see cref="OperationContext"/> for the specified <see cref="DomainOperationType"/> /// </summary> /// <param name="operationType">The type of operation context to create</param> /// <returns>An operation context for the specified type</returns> private OperationContext CreateOperationContext(DomainOperationType operationType) { // TODO: consider whether this implementation should call dispose // Maybe OperationContext would implement IDisposable... DomainServiceContext domainServiceContext = new DomainServiceContext(this.ServiceProvider, operationType); DomainService domainService = this.Factory.CreateDomainService(typeof(TDomainService), domainServiceContext); DomainServiceDescription domainServiceDescription = DomainServiceDescription.GetDescription(typeof(TDomainService)); return(new OperationContext(domainServiceContext, domainService, domainServiceDescription)); }
/// <summary> /// Initializes this <see cref="DomainService"/>. <see cref="DomainService.Initialize"/> must be called /// prior to invoking any operations on the <see cref="DomainService"/> instance. /// </summary> /// <param name="context">The <see cref="DomainServiceContext"/> for this <see cref="DomainService"/> /// instance. Overrides must call the base method.</param> public override void Initialize(DomainServiceContext context) { base.Initialize(context); // If we're going to process a query, we want to turn deferred loading // off, since the framework will access association members marked // with IncludeAttribute and we don't want to cause deferred loads. However, // for other operation types, we don't want to interfere. if (context.OperationType == DomainOperationType.Query) { this.DataContext.DeferredLoadingEnabled = false; } }
/// <summary> /// Creates an instance of the specified provider type, initialized with /// a mock operation context. /// </summary> /// <param name="providerType">The Type of provider to create and initialize</param> /// <param name="operationType">The operation type</param> /// <returns>The provider instance</returns> public static DomainService CreateInitializedDomainService(Type providerType, DomainOperationType operationType) { DomainService provider = (DomainService)Activator.CreateInstance(providerType); // create a fully functional, authenticated test context MockUser mockUser = new MockUser("test_user"); mockUser.IsAuthenticated = true; MockDataService dataService = new MockDataService(mockUser); DomainServiceContext operationContext = new DomainServiceContext(dataService, operationType); provider.Initialize(operationContext); return(provider); }
public async Task DomainService_InvalidOperationType() { TestDomainServices.EF.Northwind nw = new TestDomainServices.EF.Northwind(); DomainServiceContext dsc = new DomainServiceContext(new MockDataService(new MockUser("mathew") { IsAuthenticated = true }), DomainOperationType.Submit); nw.Initialize(dsc); DomainServiceDescription dsd = DomainServiceDescription.GetDescription(typeof(TestDomainServices.EF.Northwind)); DomainOperationEntry entry = dsd.GetQueryMethod(nameof(TestDomainServices.EF.Northwind.GetOrderDetails)); QueryDescription qd = new QueryDescription(entry); await ExceptionHelper.ExpectExceptionAsync <InvalidOperationException>(() => { return(nw.QueryAsync <NorthwindModel.Order_Detail>(qd, CancellationToken.None).AsTask()); }, string.Format(Resource.DomainService_InvalidOperationType, DomainOperationType.Submit, DomainOperationType.Query)); InvokeDescription id = new InvokeDescription(entry, null); await ExceptionHelper.ExpectExceptionAsync <InvalidOperationException>(() => { return(nw.InvokeAsync(id, CancellationToken.None).AsTask()); }, string.Format(Resource.DomainService_InvalidOperationType, DomainOperationType.Submit, DomainOperationType.Invoke)); nw = new TestDomainServices.EF.Northwind(); dsc = new DomainServiceContext(new MockDataService(new MockUser("mathew") { IsAuthenticated = true }), DomainOperationType.Query); nw.Initialize(dsc); ChangeSet cs = new ChangeSet(new ChangeSetEntry[] { new ChangeSetEntry() { Entity = new ServiceContext_CurrentOperation_Entity() { Key = 1 }, Operation = DomainOperation.Insert } }); await ExceptionHelper.ExpectExceptionAsync <InvalidOperationException>(async() => { await nw.SubmitAsync(cs, CancellationToken.None); }, string.Format(Resource.DomainService_InvalidOperationType, DomainOperationType.Query, DomainOperationType.Submit)); }
/// <summary> /// Initializes this <see cref="DomainService"/>. <see cref="DomainService.Initialize"/> must be called /// prior to invoking any operations on the <see cref="DomainService"/> instance. /// </summary> /// <param name="context">The <see cref="DomainServiceContext"/> for this <see cref="DomainService"/> /// instance. Overrides must call the base method.</param> public override void Initialize(DomainServiceContext context) { base.Initialize(context); // If we're going to process a query, we want to turn deferred loading // off, since the framework will access association members marked // with IncludeAttribute and we don't want to cause deferred loads. However, // for other operation types, we don't want to interfere. if (context.OperationType == DomainOperationType.Query) { this.ObjectContext.ContextOptions.LazyLoadingEnabled = false; } // We turn this off, since our deserializer isn't going to create // the EF proxy types anyways. Proxies only really work if the entities // are queried on the server. this.ObjectContext.ContextOptions.ProxyCreationEnabled = false; }
/// <summary> /// Helper method performs a invoke operation against a given proxy instance. /// </summary> /// <param name="domainService">The type of <see cref="DomainService"/> to perform this query operation against.</param> /// <param name="context">The current context.</param> /// <param name="domainServiceInstances">The list of tracked <see cref="DomainService"/> instances that any newly created /// <see cref="DomainServices"/> will be added to.</param> /// <param name="name">The name of the operation to invoke.</param> /// <param name="parameters">The operation parameters.</param> /// <returns>The result of the invoke operation.</returns> /// <exception cref="ArgumentNullException">if <paramref name="context"/> is null.</exception> /// <exception cref="ArgumentNullException">if <paramref name="name"/> is null or an empty string.</exception> /// <exception cref="OperationException">if operation errors are thrown during execution of the invoke operation.</exception> public static object Invoke(Type domainService, DomainServiceContext context, IList <DomainService> domainServiceInstances, string name, object[] parameters) { context = new DomainServiceContext(context, DomainOperationType.Invoke); DomainService service = CreateDomainServiceInstance(domainService, context, domainServiceInstances); DomainServiceDescription serviceDescription = DomainServiceDescription.GetDescription(service.GetType()); DomainOperationEntry method = serviceDescription.GetInvokeOperation(name); IEnumerable <ValidationResult> validationErrors; InvokeDescription invokeDescription = new InvokeDescription(method, parameters); object result = service.Invoke(invokeDescription, out validationErrors); if (validationErrors != null && validationErrors.Any()) { IEnumerable <ValidationResultInfo> operationErrors = validationErrors.Select(ve => new ValidationResultInfo(ve.ErrorMessage, ve.MemberNames)); throw new OperationException(Resource.DomainServiceProxy_OperationError, operationErrors); } return(result); }
/// <summary> /// Initializes the <see cref="DomainService"/>. <see cref="DomainService.Initialize"/> must be called /// prior to invoking any operations on the <see cref="DomainService"/> instance. /// </summary> /// <param name="context">The <see cref="DomainServiceContext"/> for this <see cref="DomainService"/> /// instance. Overrides must call the base method.</param> public override void Initialize(DomainServiceContext context) { base.Initialize(context); ObjectContext objectContext = ((IObjectContextAdapter)this.DbContext).ObjectContext; // We turn this off, since our deserializer isn't going to create // the EF proxy types anyways. Proxies only really work if the entities // are queried on the server. objectContext.ContextOptions.ProxyCreationEnabled = false; // Turn off DbContext validation. this.DbContext.Configuration.ValidateOnSaveEnabled = false; // Turn off AutoDetectChanges. this.DbContext.Configuration.AutoDetectChangesEnabled = false; this.DbContext.Configuration.LazyLoadingEnabled = false; }
public OperationContext(DomainServiceContext domainServiceContext, DomainService domainService, DomainServiceDescription domainServiceDescription) { if (domainServiceContext == null) { throw new ArgumentNullException(nameof(domainServiceContext)); } if (domainService == null) { throw new ArgumentNullException(nameof(domainService)); } if (domainServiceDescription == null) { throw new ArgumentNullException(nameof(domainServiceDescription)); } this._domainServiceContext = domainServiceContext; this._domainService = domainService; this._domainServiceDescription = domainServiceDescription; }
public void EFDomainService_AddUnmodifiedScenario() { // create an updated order with an attached new detail NorthwindModel.Order order = new NorthwindModel.Order { OrderID = 1, ShipCity = "London" }; NorthwindModel.Order origOrder = new NorthwindModel.Order { OrderID = 1, ShipCity = "Paris" }; NorthwindModel.Order_Detail detail = new NorthwindModel.Order_Detail { OrderID = 1, ProductID = 1 }; NorthwindModel.Order_Detail detail2 = new NorthwindModel.Order_Detail { OrderID = 1, ProductID = 2 }; order.Order_Details.Add(detail); order.Order_Details.Add(detail2); // create and initialize the service DomainServiceDescription dsd = DomainServiceDescription.GetDescription(typeof(TestDomainServices.EF.Northwind)); TestDomainServices.EF.Northwind nw = new TestDomainServices.EF.Northwind(); DomainServiceContext dsc = new DomainServiceContext(new MockDataService(new MockUser("mathew") { IsAuthenticated = true }), DomainOperationType.Submit); nw.Initialize(dsc); // call attach directly - this causes the detail to be attached as unmodified order.EntityKey = nw.ObjectContext.CreateEntityKey("Orders", order); origOrder.EntityKey = nw.ObjectContext.CreateEntityKey("Orders", order); ObjectContextExtensions.AttachAsModified(nw.ObjectContext.Orders, order, origOrder); // now insert the detail, and verify that even though the detail is already // attached it can be transitioned to new nw.InsertOrderDetail(detail); nw.InsertOrderDetail(detail2); Assert.AreEqual(System.Data.Entity.EntityState.Modified, order.EntityState); Assert.AreEqual(System.Data.Entity.EntityState.Added, detail.EntityState); Assert.AreEqual(System.Data.Entity.EntityState.Added, detail2.EntityState); }
public void TestDirectChangeset_Cities() { for (int i = 0; i < 100; i++) { CityDomainService ds = new CityDomainService(); DomainServiceContext dsc = new DomainServiceContext(new MockDataService(new MockUser("mathew")), DomainOperationType.Submit); ds.Initialize(dsc); List<ChangeSetEntry> entries = new List<ChangeSetEntry>(); for (int j = 0; j < 500; j++) { City newCity = new City() { Name = "Toledo", CountyName = "Lucas", StateName = "OH" }; entries.Add(new ChangeSetEntry(j, newCity, null, DomainOperation.Insert)); } ChangeSetProcessor.Process(ds, entries); Assert.IsFalse(entries.Any(p => p.HasError)); } }
// // Summary: // Initializes the System.Web.Http.ApiController instance with the specified controllerContext. // // Parameters: // controllerContext: // The System.Web.Http.Controllers.HttpControllerContext object that is used for // the initialization. protected virtual void Initialize(HttpControllerContext controllerContext) { if (_initialized) { throw System.Web.Http.Error.InvalidOperation("already initialized"); } if (controllerContext == null) { throw System.Web.Http.Error.ArgumentNull(nameof(controllerContext)); } _initialized = true; ControllerContext = controllerContext; // TODO: Resolve type first // TODO: Improve perf var operationType = DomainOperationType.Query; var context = new DomainServiceContext(new ServiceContainerWrapper(controllerContext), operationType); base.Initialize(context); }
/// <summary> /// Helper method performs a invoke operation against a given proxy instance. /// </summary> /// <param name="domainService">The type of <see cref="DomainService"/> to perform this query operation against.</param> /// <param name="context">The current context.</param> /// <param name="domainServiceInstances">The list of tracked <see cref="DomainService"/> instances that any newly created /// <see cref="DomainServices"/> will be added to.</param> /// <param name="name">The name of the operation to invoke.</param> /// <param name="parameters">The operation parameters.</param> /// <returns>The result of the invoke operation.</returns> /// <exception cref="ArgumentNullException">if <paramref name="context"/> is null.</exception> /// <exception cref="ArgumentNullException">if <paramref name="name"/> is null or an empty string.</exception> /// <exception cref="OperationException">if operation errors are thrown during execution of the invoke operation.</exception> public static object Invoke(Type domainService, DomainServiceContext context, IList <DomainService> domainServiceInstances, string name, object[] parameters) { context = new DomainServiceContext(context, DomainOperationType.Invoke); DomainService service = CreateDomainServiceInstance(domainService, context, domainServiceInstances); DomainServiceDescription serviceDescription = DomainServiceDescription.GetDescription(service.GetType()); DomainOperationEntry method = serviceDescription.GetInvokeOperation(name); InvokeDescription invokeDescription = new InvokeDescription(method, parameters); // TODO: Look into removing this blocking Wait var loadResult = service.InvokeAsync(invokeDescription, CancellationToken.None) .GetAwaiter().GetResult(); if (loadResult.HasValidationErrors) { IEnumerable <ValidationResultInfo> operationErrors = loadResult.ValidationErrors.Select(ve => new ValidationResultInfo(ve.ErrorMessage, ve.MemberNames)); throw new OperationException(Resource.DomainServiceProxy_OperationError, operationErrors); } return(loadResult.Result); }
public void Create_DomainServiceContext() { var context = new MockDomainServiceContext(DomainOperationType.Query); // Create proxy, verify it's not null. var proxy = DomainServiceProxy.Create <IMockDomainServiceContract, MockDomainService>(context); Assert.IsNotNull(proxy); // Examine its Context property PropertyInfo contextProp = proxy.GetType().GetProperty("Context"); DomainServiceContext proxyContext = (DomainServiceContext)contextProp.GetGetMethod().Invoke(proxy, null); Assert.AreSame(context, proxyContext); // Examine its DomainServiceType property PropertyInfo typeProp = proxy.GetType().GetProperty("DomainServiceType"); Type proxyType = (Type)typeProp.GetGetMethod().Invoke(proxy, null); Assert.AreEqual(typeof(MockDomainService), proxyType); }
/// <summary> /// Helper method performs a submit operation against a given proxy instance. /// </summary> /// <param name="domainService">The type of <see cref="DomainService"/> to perform this query operation against.</param> /// <param name="context">The current context.</param> /// <param name="domainServiceInstances">The list of tracked <see cref="DomainService"/> instances that any newly created /// <see cref="DomainServices"/> will be added to.</param> /// <param name="currentOriginalEntityMap">The mapping of current and original entities used with the utility <see cref="DomainServiceProxy.AssociateOriginal"/> method.</param> /// <param name="entity">The entity being submitted.</param> /// <param name="operationName">The name of the submit operation. For CUD operations, this can be null.</param> /// <param name="parameters">The submit operation parameters.</param> /// <param name="domainOperation">The type of submit operation.</param> /// <exception cref="ArgumentNullException">if <paramref name="context"/> is null.</exception> /// <exception cref="ArgumentNullException">if <paramref name="entity"/> is null.</exception> /// <exception cref="OperationException">if operation errors are thrown during execution of the submit operation.</exception> public static void Submit(Type domainService, DomainServiceContext context, IList <DomainService> domainServiceInstances, IDictionary <object, object> currentOriginalEntityMap, object entity, string operationName, object[] parameters, DomainOperation domainOperation) { context = new DomainServiceContext(context, DomainOperationType.Submit); DomainService service = CreateDomainServiceInstance(domainService, context, domainServiceInstances); object originalEntity = null; currentOriginalEntityMap.TryGetValue(entity, out originalEntity); // if this is an update operation, regardless of whether original // values have been specified, we need to mark the operation as // modified bool hasMemberChanges = domainOperation == DomainOperation.Update; // when custom methods are invoked, the operation type // is Update if (domainOperation == DomainOperation.Custom) { domainOperation = DomainOperation.Update; } ChangeSetEntry changeSetEntry = new ChangeSetEntry(1, entity, originalEntity, domainOperation); changeSetEntry.HasMemberChanges = hasMemberChanges; if (!string.IsNullOrEmpty(operationName)) { changeSetEntry.EntityActions = new List <Serialization.KeyValue <string, object[]> >(); changeSetEntry.EntityActions.Add(new Serialization.KeyValue <string, object[]>(operationName, parameters)); } ChangeSet changeSet = new ChangeSet(new[] { changeSetEntry }); service.SubmitAsync(changeSet, CancellationToken.None) .GetAwaiter().GetResult(); if (changeSetEntry.HasError) { throw new OperationException(Resource.DomainServiceProxy_OperationError, changeSetEntry.ValidationErrors); } }
/// <summary> /// Helper method performs a query operation against a given proxy instance. /// </summary> /// <param name="domainService">The type of <see cref="DomainService"/> to perform this query operation against.</param> /// <param name="context">The current context.</param> /// <param name="domainServiceInstances">The list of tracked <see cref="DomainService"/> instances that any newly created /// <see cref="DomainServices"/> will be added to.</param> /// <param name="queryName">The name of the query to invoke.</param> /// <param name="parameters">The query parameters.</param> /// <returns>The query results. May be null if there are no query results.</returns> /// <exception cref="ArgumentNullException">if <paramref name="context"/> is null.</exception> /// <exception cref="ArgumentNullException">if <paramref name="queryName"/> is null or an empty string.</exception> /// <exception cref="InvalidOperationException">if no match query operation exists on the <paramref name="context"/>.</exception> /// <exception cref="OperationException">if operation errors are thrown during execution of the query operation.</exception> public static IEnumerable Query(Type domainService, DomainServiceContext context, IList <DomainService> domainServiceInstances, string queryName, object[] parameters) { context = new DomainServiceContext(context, DomainOperationType.Query); DomainService service = CreateDomainServiceInstance(domainService, context, domainServiceInstances); DomainServiceDescription serviceDescription = DomainServiceDescription.GetDescription(service.GetType()); DomainOperationEntry queryOperation = serviceDescription.GetQueryMethod(queryName); if (queryOperation == null) { string errorMessage = string.Format( CultureInfo.InvariantCulture, Resource.DomainServiceProxy_QueryOperationNotFound, queryName, domainService); throw new InvalidOperationException(errorMessage); } IEnumerable <ValidationResult> validationErrors; object[] parameterValues = parameters ?? Array.Empty <object>(); QueryDescription queryDescription = new QueryDescription(queryOperation, parameterValues); // TODO: Look into removing this blocking Wait var actualMethod = s_queryAsync.MakeGenericMethod(queryDescription.Method.AssociatedType); var queryResult = ((ValueTask <ServiceQueryResult>)actualMethod.Invoke(service, new object[] { queryDescription, CancellationToken.None })) .GetAwaiter().GetResult(); validationErrors = queryResult.ValidationErrors; var result = queryResult.Result; if (validationErrors != null && validationErrors.Any()) { IEnumerable <ValidationResultInfo> operationErrors = validationErrors.Select(ve => new ValidationResultInfo(ve.ErrorMessage, ve.MemberNames)); throw new OperationException(Resource.DomainServiceProxy_OperationError, operationErrors); } return(result); }
/// <summary> /// Instatiates a DomainService instance along with the DomainServiceContext. /// </summary> /// <param name="instance">Wrapper representing the instance passed to invocation.</param> /// <returns>New DomainService instance.</returns> private DomainService GetDomainService(object instance) { // Create and initialize the DomainService for this request. DomainDataServiceContractBehavior.DomainDataServiceInstanceInfo instanceInfo = (DomainDataServiceContractBehavior.DomainDataServiceInstanceInfo)instance; IServiceProvider serviceProvider = (IServiceProvider)OperationContext.Current.Host; DomainServiceContext context = new DomainServiceContext(serviceProvider, this.operationType); try { DomainService domainService = DomainService.Factory.CreateDomainService(instanceInfo.DomainServiceType, context); instanceInfo.DomainServiceInstance = domainService; return(domainService); } catch (TargetInvocationException tie) { // If the exception has already been transformed to a DomainServiceException just rethrow it. if (tie.InnerException != null) { throw new DomainDataServiceException(Resource.DomainDataService_General_Error, tie.InnerException); } throw new DomainDataServiceException(Resource.DomainDataService_General_Error, tie); } catch (Exception ex) { if (ex.IsFatal()) { throw; } else { // We need to ensure that any time an exception is thrown by the service it is transformed to a // properly sanitized/configured DomainDataService exception. throw new DomainDataServiceException(Resource.DomainDataService_General_Error, ex); } } }
public void DomainService_DirectQuery() { DomainServiceDescription description = DomainServiceDescription.GetDescription(typeof(TestDomainServices.EF.Catalog)); TestDomainServices.EF.Catalog service = new TestDomainServices.EF.Catalog(); DomainServiceContext dsc = new DomainServiceContext(new MockDataService(new MockUser("mathew") { IsAuthenticated = true }), DomainOperationType.Query); service.Initialize(dsc); DomainOperationEntry queryOperation = description.GetQueryMethod("GetPurchaseOrders"); ServiceQuery serviceQuery = new ServiceQuery(); serviceQuery.QueryParts = new ServiceQueryPart[] { new ServiceQueryPart("where", "(it.Freight!=0)"), new ServiceQueryPart("take", "1") }; IEnumerable<ValidationResult> validationErrors; int totalCount; QueryResult<AdventureWorksModel.PurchaseOrder> result = QueryProcessor.Process<AdventureWorksModel.PurchaseOrder>(service, queryOperation, new object[0], serviceQuery, out validationErrors, out totalCount); Assert.AreEqual(1, result.RootResults.Count()); }
public void Authorization_Custom_Authorization_On_CUD() { // Specifically, the City data is marked so that no one can delete a Zip code // from WA unless their user name is WAGuy MockUser notWaGuy = new MockUser("notWAGuy"); notWaGuy.IsAuthenticated = true; DomainServiceDescription serviceDescription = DomainServiceDescription.GetDescription(typeof(CityDomainService)); Zip zip = null; // First execute a query to get some zips DomainOperationEntry getZipsQuery = serviceDescription.GetQueryMethod("GetZips"); DomainServiceContext ctxt = new DomainServiceContext(new MockDataService(notWaGuy), DomainOperationType.Query); using (CityDomainService cities = new CityDomainService()) { // Now prepare for a query to find a Zip in WA ctxt = new DomainServiceContext(new MockDataService(notWaGuy), DomainOperationType.Query); cities.Initialize(ctxt); int count = -1; IEnumerable<ValidationResult> validationErrors = null; IEnumerable result = cities.Query(new QueryDescription(getZipsQuery), out validationErrors, out count); zip = result.OfType<Zip>().FirstOrDefault(z => z.StateName == "WA"); Assert.IsNotNull(zip, "Could not find a zip code in WA"); } // Prepare a submit to delete this zip from a user who is not authorized using (CityDomainService cities = new CityDomainService()) { // Now prepare for a query to find a Zip in WA ctxt = new DomainServiceContext(new MockDataService(notWaGuy), DomainOperationType.Submit); cities.Initialize(ctxt); // Prepare an attempt to delete this with a user whose name is not WAGuy // This should fail due to a custom auth attribute List<ChangeSetEntry> entries = new List<ChangeSetEntry>(); ChangeSetEntry entry = new ChangeSetEntry(1, zip, zip, DomainOperation.Delete); entries.Add(entry); UnauthorizedAccessException exception = null; try { ChangeSetProcessor.Process(cities, entries); } catch (UnauthorizedAccessException ex) { exception = ex; } Assert.IsNotNull(exception, "Expected failure attempting to delete a zip from WA with inappropriate user name"); Assert.AreEqual("Only one user can delete zip codes from that state, and it isn't you.", exception.Message); } // Now do that again but with a user who is WAGuy -- it should succeed using (CityDomainService cities = new CityDomainService()) { MockUser waGuy = new MockUser("WAGuy"); waGuy.IsAuthenticated = true; // Now try a submit where the user *is* Mathew to validate we succeed ctxt = new DomainServiceContext(new MockDataService(waGuy), DomainOperationType.Submit); cities.Initialize(ctxt); List<ChangeSetEntry> entries = new List<ChangeSetEntry>(); ChangeSetEntry entry = new ChangeSetEntry(1, zip, zip, DomainOperation.Delete); entries.Add(entry); Exception exception = null; try { ChangeSetProcessor.Process(cities, entries); } catch (UnauthorizedAccessException ex) { exception = ex; } Assert.IsNull(exception, "Expected success attempting to delete a zip from WA with inappropriate user name"); } }
public void Authorization_Custom_Authorization_On_Custom_Update() { // Specifically, the City data is marked so that no one can delete a Zip code // from WA unless their user name is WAGuy MockUser notWaGuy = new MockUser("notWAGuy"); notWaGuy.IsAuthenticated = true; DomainServiceDescription serviceDescription = DomainServiceDescription.GetDescription(typeof(CityDomainService)); City city = null; // Execute a query to get a City from WA using (CityDomainService cities = new CityDomainService()) { DomainOperationEntry getCitiesQuery = serviceDescription.GetQueryMethod("GetCities"); // Now prepare for a query to find a Zip in WA DomainServiceContext ctxt = new DomainServiceContext(new MockDataService(notWaGuy), DomainOperationType.Query); cities.Initialize(ctxt); int count = -1; IEnumerable<ValidationResult> validationErrors = null; IEnumerable result = cities.Query(new QueryDescription(getCitiesQuery), out validationErrors, out count); city = result.OfType<City>().FirstOrDefault(z => z.StateName == "WA"); Assert.IsNotNull(city, "Could not find a city in WA"); } using (CityDomainService cities = new CityDomainService()) { // Now prepare for a submit to invoke AssignCityZoneIfAuthorized as a named update method DomainServiceContext ctxt = new DomainServiceContext(new MockDataService(notWaGuy), DomainOperationType.Submit); cities.Initialize(ctxt); // Prepare an attempt to delete this with a user whose name is not WAGuy // This should fail due to a custom auth attribute List<ChangeSetEntry> entries = new List<ChangeSetEntry>(); ChangeSetEntry entry = new ChangeSetEntry(); entry.DomainOperationEntry = serviceDescription.GetCustomMethod(typeof(City), "AssignCityZoneIfAuthorized"); entry.EntityActions = new EntityActionCollection { { "AssignCityZoneIfAuthorized", new object[] { "SomeZone" } } }; entry.Operation = DomainOperation.Update; entry.Entity = city; entries.Add(entry); UnauthorizedAccessException exception = null; try { ChangeSetProcessor.Process(cities, entries); } catch (UnauthorizedAccessException ex) { exception = ex; } Assert.IsNotNull(exception, "Expected failure attempting to perform custom method on WA with inappropriate user name"); Assert.AreEqual("Only one user is authorized to execute operation 'AssignCityZoneIfAuthorized', and it isn't you.", exception.Message); } // Now do that again but with a user who is WAGuy -- it should succeed using (CityDomainService cities = new CityDomainService()) { MockUser waGuy = new MockUser("WAGuy"); waGuy.IsAuthenticated = true; // Now prepare for a submit to invoke AssignCityZoneIfAuthorized as a named update method DomainServiceContext ctxt = new DomainServiceContext(new MockDataService(waGuy), DomainOperationType.Submit); cities.Initialize(ctxt); // Prepare an attempt to delete this with a user whose name is not WAGuy // This should fail due to a custom auth attribute // Prepare a submit to call the AssignCityZoneIfAuthorized with an unauthorized user List<ChangeSetEntry> entries = new List<ChangeSetEntry>(); ChangeSetEntry entry = new ChangeSetEntry(); entry.DomainOperationEntry = serviceDescription.GetCustomMethod(typeof(City), "AssignCityZoneIfAuthorized"); entry.EntityActions = new EntityActionCollection { { "AssignCityZoneIfAuthorized", new object[] { "SomeZone" } } }; entry.Operation = DomainOperation.Update; entry.Entity = city; entries.Add(entry); Exception exception = null; try { ChangeSetProcessor.Process(cities, entries); } catch (UnauthorizedAccessException ex) { exception = ex; } Assert.IsNull(exception, "Expected success attempting to delete a zip from WA with inappropriate user name"); } }
public void Authorization_Custom_Authorization_On_Invoke() { // Specifically, the City data is marked so that no one can delete a Zip code // from WA unless their user name is WAGuy MockUser notWaGuy = new MockUser("notWAGuy"); notWaGuy.IsAuthenticated = true; DomainServiceDescription serviceDescription = DomainServiceDescription.GetDescription(typeof(CityDomainService)); DomainOperationEntry invokeOperation = serviceDescription.GetInvokeOperation("GetStateIfUser"); Assert.IsNotNull(invokeOperation, "Could not locate GetStateIfUser Invoke operation"); DomainOperationEntry getCitiesQuery = serviceDescription.GetQueryMethod("GetCities"); City city = null; // Execute a query to get a City from WA using (CityDomainService cities = new CityDomainService()) { // Now prepare for a query to find a Zip in WA DomainServiceContext ctxt = new DomainServiceContext(new MockDataService(notWaGuy), DomainOperationType.Query); cities.Initialize(ctxt); int count = -1; IEnumerable<ValidationResult> validationErrors = null; IEnumerable result = cities.Query(new QueryDescription(getCitiesQuery), out validationErrors, out count); city = result.OfType<City>().FirstOrDefault(z => z.StateName == "WA"); Assert.IsNotNull(city, "Could not find a city in WA"); } // Perform an invoke against a method that has a custom auth attribute requiring WaGuy // where the user is something else -- should be denied using (CityDomainService cities = new CityDomainService()) { // Prepare an invoke to call a method that has a custom auth attribute DomainServiceContext ctxt = new DomainServiceContext(new MockDataService(notWaGuy), DomainOperationType.Invoke); cities.Initialize(ctxt); // verify that even top level exceptions go through // the OnError handler IEnumerable<ValidationResult> validationErrors; UnauthorizedAccessException expectedException = null; try { // cause a domain service not initialized exception cities.Invoke(new InvokeDescription(invokeOperation, new object[] { city }), out validationErrors); } catch (UnauthorizedAccessException e) { expectedException = e; } Assert.IsNotNull(expectedException, "Expected Invoke to be denied"); Assert.AreEqual("Access to operation 'GetStateIfUser' was denied.", expectedException.Message); } // Perform an invoke against a method that has a custom auth attribute requiring WaGuy // where the user is correct -- should be allowed using (CityDomainService cities = new CityDomainService()) { MockUser waGuy = new MockUser("WAGuy"); waGuy.IsAuthenticated = true; // Prepare an invoke to call a method that has a custom auth attribute DomainServiceContext ctxt = new DomainServiceContext(new MockDataService(waGuy), DomainOperationType.Invoke); cities.Initialize(ctxt); // verify that even top level exceptions go through // the OnError handler IEnumerable<ValidationResult> validationErrors; UnauthorizedAccessException expectedException = null; try { // cause a domain service not initialized exception cities.Invoke(new InvokeDescription(invokeOperation, new object[] { city }), out validationErrors); } catch (UnauthorizedAccessException e) { expectedException = e; } Assert.IsNull(expectedException, "Expected Invoke to be allowed"); } }
public void DomainService_InvalidOperationType() { TestDomainServices.EF.Northwind nw = new TestDomainServices.EF.Northwind(); DomainServiceContext dsc = new DomainServiceContext(new MockDataService(new MockUser("mathew") { IsAuthenticated = true }), DomainOperationType.Submit); nw.Initialize(dsc); IEnumerable<ValidationResult> validationResults = null; int totalCount; DomainServiceDescription dsd = DomainServiceDescription.GetDescription(typeof(TestDomainServices.EF.Northwind)); DomainOperationEntry entry = dsd.DomainOperationEntries.First(p => p.Operation == DomainOperation.Query); QueryDescription qd = new QueryDescription(entry); ExceptionHelper.ExpectException<InvalidOperationException>(delegate { nw.Query(qd, out validationResults, out totalCount); }, string.Format(Resource.DomainService_InvalidOperationType, DomainOperationType.Submit, DomainOperationType.Query)); InvokeDescription id = new InvokeDescription(entry, null); ExceptionHelper.ExpectException<InvalidOperationException>(delegate { nw.Invoke(id, out validationResults); }, string.Format(Resource.DomainService_InvalidOperationType, DomainOperationType.Submit, DomainOperationType.Invoke)); nw = new TestDomainServices.EF.Northwind(); dsc = new DomainServiceContext(new MockDataService(new MockUser("mathew") { IsAuthenticated = true }), DomainOperationType.Query); nw.Initialize(dsc); ChangeSet cs = new ChangeSet(new ChangeSetEntry[] { new ChangeSetEntry() { Entity = new ServiceContext_CurrentOperation_Entity() { Key = 1 }, Operation = DomainOperation.Insert } }); ExceptionHelper.ExpectException<InvalidOperationException>(delegate { nw.Submit(cs); }, string.Format(Resource.DomainService_InvalidOperationType, DomainOperationType.Query, DomainOperationType.Submit)); }
/// <summary> /// Creates a new <see cref="DomainService" /> instance. /// </summary> /// <param name="domainServiceType">The <see cref="Type" /> of <see cref="DomainService" /> to create.</param> /// <param name="context">The current <see cref="DomainServiceContext" />.</param> /// <returns> /// A <see cref="DomainService" /> instance. /// </returns> public DomainService CreateDomainService(Type domainServiceType, DomainServiceContext context) { return (DomainService)RequestLifetimeScope.Resolve(domainServiceType, TypedParameter.From(context)); }
public DomainService CreateDomainService(System.Type domainServiceType, DomainServiceContext context) { var service =ServiceLocator.Current.GetInstance(domainServiceType) as DomainService; service.Initialize(context); return service; }
public void TestDirectChangeset_Simple() { for (int i = 0; i < 100; i++) { TestDomainServices.TestProvider_Scenarios ds = new TestDomainServices.TestProvider_Scenarios(); DomainServiceContext dsc = new DomainServiceContext(new MockDataService(new MockUser("mathew")), DomainOperationType.Submit); ds.Initialize(dsc); List<ChangeSetEntry> entries = new List<ChangeSetEntry>(); for (int j = 0; j < 500; j++) { TestDomainServices.POCONoValidation e = new TestDomainServices.POCONoValidation() { ID = i, A = "A" + i, B = "B" + i, C = "C" + i, D = "D" + i, E = "E" + i }; entries.Add(new ChangeSetEntry(j, e, null, DomainOperation.Insert)); } ChangeSetProcessor.Process(ds, entries); Assert.IsFalse(entries.Any(p => p.HasError)); } }
public DomainService CreateDomainService(Type domainServiceType, DomainServiceContext context) { var service = Container.Instance.Resolve(domainServiceType) as DomainService; if (service != null) service.Initialize(context); return service; }