/// <summary> /// Sets the Database initializer associated to the DbContext with the given value. /// </summary> /// <param name="contextType">The type of the DbContext for which we want to set the value of the Database initializer.</param> /// <param name="dbContextTypeReference">The reference to DbContext type (or typeof(DbContext)).</param> /// <param name="initializer">The initializer object.</param> public static void SetDbInitializer(Type contextType, Type dbContextTypeReference, object initializer) { // We need the context type and the reference to DbContext type to be not null to set the database initializer. if (contextType == null || dbContextTypeReference == null) { return; } // Here, we basically need to do this: Database.SetInitializer<typeof(ContextType)>(initializer); // Load typeof(Database) from the EntityFramework assembly. Type databaseType = DbContextUtilities.LoadTypeFromAssembly(dbContextTypeReference.Assembly, DbContextUtilities.DatabaseTypeName); if (databaseType != null) { // Get the method Database.SetInitializer<DbContext>(IDatabaseInitializer<DbContext>); Type databaseInitializerType = dbContextTypeReference.Assembly.GetType(DbContextUtilities.IDatabaseInitializerTypeName); if (databaseInitializerType != null && databaseInitializerType.IsGenericType) { databaseInitializerType = databaseInitializerType.MakeGenericType(new Type[] { dbContextTypeReference }); MethodInfo setInitializerMethod = databaseType.GetMethod("SetInitializer", new Type[] { databaseInitializerType }); if (setInitializerMethod != null && setInitializerMethod.IsGenericMethod) { // Add the DbContext generic parameter to the method. MethodInfo genericSetInitializerMethod = setInitializerMethod.MakeGenericMethod(new Type[] { contextType }); if (genericSetInitializerMethod != null) { // We found the right method. Now invoke it with the initializer parameter. genericSetInitializerMethod.Invoke(null, new object[] { initializer }); } } } } }
private void AddDomainServiceType(Type domainServiceType) { bool enableClientAccess = TypeDescriptor.GetAttributes(domainServiceType)[typeof(EnableClientAccessAttribute)] != null; // The DomainService Type must be marked with EnableClientAccess attribute if (!enableClientAccess) { this.LogError(string.Format(CultureInfo.CurrentCulture, Resource.ClientCodeGen_InvalidDomainServiceType, domainServiceType.Name)); return; } // EF CodeFirst tries to initialize the Database when we new up a DbContext. We want to avoid that at design time. // So disable the Database initializer if it is a DbContext based DomainService. Type contextType = DbContextUtilities.GetDbContextType(domainServiceType); if (contextType != null) { // From the context type, get typeof(DbContext) Type dbContextTypeRef = DbContextUtilities.GetDbContextTypeReference(contextType); System.Diagnostics.Debug.Assert(dbContextTypeRef != null, "If we have the DbContext type, typeof(DbContext) should not be null"); DbContextUtilities.SetDbInitializer(contextType, dbContextTypeRef, null); } try { DomainServiceDescription description = this.GetProviderDescription(domainServiceType); if (description != null) { if (description.EntityTypes.Any() || description.DomainOperationEntries.Any(p => p.Operation == DomainOperation.Invoke)) { this._domainServiceDescriptions.Add(description); } else { this.LogWarning(string.Format(CultureInfo.CurrentCulture, Resource.ClientCodeGen_EmptyDomainService, domainServiceType.Name)); } } } catch (ArgumentException ae) { // Our DPD layer reports problems only by throwing. // Translate these exceptions into clean error logs // so that they appear in the Error window in VS this.LogError(ae.Message); } catch (InvalidOperationException ioe) { this.LogError(ioe.Message); } }
/// <summary> /// Returns the DbContext type given the <see cref="DomainService"/> type. Uses late binding so as to avoid adding a reference to EF 4.1. /// </summary> /// <param name="domainServiceType">The type of the domain service.</param> /// <returns>The type of the DbContext.</returns> public static Type GetDbContextType(Type domainServiceType) { Type dbContextType = null; Type currType = domainServiceType; while (currType != null && currType != typeof(object) && currType != typeof(DomainService)) { if (currType.IsGenericType && DbContextUtilities.CompareWithSystemType(currType, DbContextUtilities.DbDomainServiceTypeName)) { Type[] typeArgs = currType.GetGenericArguments(); if (typeArgs != null && typeArgs.Count() > 0) { dbContextType = typeArgs[0]; } break; } currType = currType.BaseType; } return(dbContextType); }
/// <summary> /// Checks if this type is assignable from typeof(DbContext). /// </summary> /// <param name="type">The type to check if it is a DbContext.</param> /// <returns><c>true</c> is the type is a DbContext, <c>false</c> otherwise.</returns> public static bool IsDbContext(this Type type) { // If we have a reference to typeof(DbContext), then check if type is assignable from it. if (DbContextUtilities._dbContextTypeReference != null) { return(DbContextUtilities._dbContextTypeReference.IsAssignableFrom(type)); } else { // If we don't have reference to typeof(DbContext), then compare the base types to see if one of them is the EntityFramework DbContext type. // If we find a match, we also find the DbContext type. So populate the _dbContextTypeReference with that value. Type t = DbContextUtilities.GetDbContextTypeReference(type); if (t != null) { return(true); } else { return(false); } } }
/// <summary> /// Finds the reference to System.Data.Entity.DbContext type given the contextType, if it exists. /// </summary> /// <param name="contextType">The context type from which the DbContext type reference is to be found</param> /// <returns>The reference to DbContext type.</returns> public static Type GetDbContextTypeReference(Type contextType) { if (DbContextUtilities._dbContextTypeReference == null) { // if contextType is an interface or a value type, then we know it is not a DbContext type. if (!contextType.IsInterface && !contextType.IsValueType) { Type t = contextType; // If the type if null or object, then it is not the DbContext type. // We need to check for null as well, since Walking an interface hierarchy does not lead to Object. while (t != null && t != typeof(object)) { if (DbContextUtilities.CompareWithSystemType(t, DbContextUtilities.DbContextTypeName)) { DbContextUtilities._dbContextTypeReference = t; break; } t = t.BaseType; } } } return(DbContextUtilities._dbContextTypeReference); }