3

I have a T4 template which generates a DbContext and a migration configuration. During runtime, I use that template to create an assembly, then use that assembly to generate a migration. However, when I want to do an update database, still programmatically. I get an error, however:

Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "EFMigrations._11_01_30.resources" was correctly embedded or linked into assembly "AutomatedMigrations" at compile time, or that all the satellite assemblies required are loadable and fully signed.

The code for creating the assembly:

var configuration = (DbMigrationsConfiguration)icc.CompiledAssembly.CreateInstance("EFMigrations.Configuration");
File.WriteAllText(directory + scaffold.MigrationId + ".designer.cs", scaffold.DesignerCode);
File.WriteAllText(directory + scaffold.MigrationId + ".cs", scaffold.UserCode);

using (var writer = new ResXResourceWriter(directory + scaffold.MigrationId + ".resources"))
{
    foreach (var resource in scaffold.Resources)
        writer.AddResource(resource.Key, resource.Value);
}

var filesContents = Directory.GetFiles(directory).Where(x => x.EndsWith(".cs")).Select(File.ReadAllText).ToList();
var resources = Directory.GetFiles(directory).Where(x => x.EndsWith(".resources"));
compilerParams.EmbeddedResources.AddRange(resources.ToArray());

var assemblies = provider.CompileAssemblyFromSource(compilerParams, filesContents.ToArray());
configuration.MigrationsAssembly = assemblies.CompiledAssembly;
configuration.MigrationsNamespace = "EFMigrations";
var migrator = new DbMigrator(configuration);
migrator.Update();

The exception is thrown on the Update() line.

Update:

I've performed a small hack to resolve that issue (by naming my resource Namespace.Class.resources, however now I am getting an error:

Stream is not a valid resource file

Update 2:

I have resolved the issue by creating another T4 runtime template and placing the values from the resources directly into it. It's a hackish solution, but it works for my purposes. However I'm still annoyed by the behaviour of the resource file and why it doesn't like the generated resource file.

NeroS
  • 1,179
  • 1
  • 12
  • 28
  • Did you make sure "EFMigrations._11_01_30.resources" was correctly embedded or linked into assembly "AutomatedMigrations" at compile time, and that all the satellite assemblies required are loadable and fully signed? – Robert Harvey Jan 28 '14 at 23:30
  • That's sort of quoting the fairly obvious error. The files that have been added to the compilerparams embeddedresources exist. Whether they actually get embedded... that's something I don't know because "assemblies" don't seem to have anything relating to resources, and I'm thinking that trying to use a ResourceManager will only give me the same error because it's not really related to that... I'll check that in a bit though and update. – NeroS Jan 29 '14 at 09:00
  • As I expected, ResourceManager gives me the exact same error. Am I perhaps doing something wrong in embedding the resource? – NeroS Jan 29 '14 at 09:28
  • Small update to the original post. – NeroS Jan 29 '14 at 18:55

1 Answers1

2

Just to mark this as answered - I have resolved my particular issue by creating another t4 generator which uses a sample of the designer code as base and fills in MigrationMetadataID and Target with the ones from scaffold resources like this:

var designerGenerator = new MigrationDesignerGenerator();
designerGenerator.Session = new Dictionary<string, object>();
designerGenerator.Session.Add("Target", scaffold.Resources["Target"]);
designerGenerator.Session.Add("MigrationId", scaffold.MigrationId);
designerGenerator.Initialize();
File.WriteAllText(directory + scaffold.MigrationId + ".Designer.cs", designerGenerator.TransformText());

I have excluded the ResourceManager field from the metadata generator, and used this as target instead:

string IMigrationMetadata.Target
{
    get { return "<#= Target #>"; }
}

I have come no further to solving the Resx file issue, but I will forget this for now - as hackish as this feels, it works and it works well based on my tests.

NeroS
  • 1,179
  • 1
  • 12
  • 28