private void RegisterGenericDbcModelServices(ContainerBuilder builder, Type dbcType) { //TODO: Move this to DbcTypeParser GenericDbcModelAttribute genericAttri = dbcType.GetCustomAttribute <GenericDbcModelAttribute>(); if (genericAttri == null) { throw new InvalidOperationException($"Encountered generic Model: {dbcType.Name} that did not have {nameof(GenericDbcModelAttribute)} marked."); } //Must be for the database model type //it reads the DB model type from the table builder.RegisterType(typeof(DatabaseDbcEntryReader <>).MakeGenericType(genericAttri.ClosedGenericForDatabase)) .AsImplementedInterfaces() .SingleInstance(); //For file type builder.RegisterType(typeof(GDbcFullFileGenerator <>).MakeGenericType(genericAttri.ClosedGenericForDatabase)) .As(typeof(IDbcFileGenerator <>).MakeGenericType(genericAttri.ClosedGenericForDatabase)) .SingleInstance(); builder.RegisterType(typeof(StreamBasedGDbcEntryWriter <>).MakeGenericType(genericAttri.ClosedGenericForDatabase)) .As(typeof(IDbcEntryWriter <>).MakeGenericType(genericAttri.ClosedGenericForDatabase)) .SingleInstance(); //GenericDbcFileGeneratorFillable<TDbcFileType, TDbcEntryType> builder.RegisterType(typeof(GenericDbcFileGeneratorFillable <,>).MakeGenericType(genericAttri.ClosedGenericForDatabase, genericAttri.ClosedGenericForDatabase)) .As <IDbcTargetFillable>() .SingleInstance(); builder.RegisterType(typeof(TypeConverterStub <>).MakeGenericType(genericAttri.ClosedGenericForDatabase)) .As(typeof(ITypeConverterProvider <,>).MakeGenericType(genericAttri.ClosedGenericForDatabase, genericAttri.ClosedGenericForDatabase)) .SingleInstance(); }
/// <summary> /// Similar to <see cref="RegisterNonGenericDbcModelServices"/> but handles the cases /// where a TStringType generic type arg may need to be handled and dealt with. /// </summary> /// <param name="builder"></param> /// <param name="dbcModelType"></param> /// <param name="pathParameter"></param> private void RegisterGenericDbcModelServices([NotNull] ContainerBuilder builder, [NotNull] Type dbcModelType, [NotNull] TypedParameter pathParameter) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } if (dbcModelType == null) { throw new ArgumentNullException(nameof(dbcModelType)); } if (pathParameter == null) { throw new ArgumentNullException(nameof(pathParameter)); } GenericDbcModelAttribute genericAttri = dbcModelType.GetCustomAttribute <GenericDbcModelAttribute>(); if (genericAttri == null) { throw new InvalidOperationException($"Encountered generic Model: {dbcModelType.Name} that did not have {nameof(GenericDbcModelAttribute)} marked."); } //We can use the model attributes Types for the purposes of registeration //and we trust that they are correct. //We supply it he database model type because that is what the inserter should know about. RegisterEntryInserter(builder, genericAttri.ClosedGenericForDatabase, pathParameter); RegisterDbcFileReader(builder, genericAttri.ClosedGenericForFile, pathParameter); //We actually use the DBC model file type here. This type has a dependency on an inserter //of that generic parameter so it will find the above inserter does not work. //To handle this we register a type specific to generic handlers RegisterFileToDatabaseConverter(builder, genericAttri.ClosedGenericForFile); //This will be the IDatabaseDbcInsertable<TDBCFileType> that the above converter looks for //This itself will dispatch to the one registered in RegisterEntryInserter builder.RegisterType(typeof(ConvertRequiredDatabaseEntryInserterDecorator <,>) .MakeGenericType(genericAttri.ClosedGenericForFile, genericAttri.ClosedGenericForDatabase)) .AsImplementedInterfaces() .SingleInstance(); //We also need the generic converter too, which is only needed when it's generic. builder.RegisterType(typeof(DbcRefToStringTypeConverter <,>).MakeGenericType(genericAttri.ClosedGenericForFile, genericAttri.ClosedGenericForDatabase)) .AsImplementedInterfaces() .SingleInstance(); RegisterSerializerService(builder, genericAttri.ClosedGenericForFile); }