@Алекс,
Я потратил на это много времени. Я не смог найти такой простой способ, как ваш метакод в вопросе. Я буду рад улучшениям ниже.
Моя потребность может отличаться от вашей, поэтому позвольте мне объяснить:
- Легко создать экземпляр класса по строке. Здесь на SO много примеров.
- Что НЕ просто (я почти уверен), так это то, как создать экземпляр класса, который вы можете просто добавить в свой контекст:
ctx.SomeModels.Add(myClass);
... который будет работать с:
ctx.SaveChanges();
- Я обнаружил, что класс в игре должен исходить из DbContext, чтобы он мог принять его обратно или даже использовать в Delete()...
Если это соответствует вашему сценарию, это может помочь.
Примечания:
- Я удалил все свои журналы (с помощью NLog), что добавляет много отладки, но затрудняет чтение.
- Если вы сделаете несколько точек останова и посмотрите на значения и варианты , вы увидите некоторые вещи, которые мне пришлось исправить.
- Проблема состоит из 2 частей:
1. Нахождение версии сборки имени класса из простой.
2. Использование этого удобного для компьютера имени для создания класса, который заставит DbContext не жаловаться:
/****************************************************************
*
* CreateInstanceOf
* DbTableName = SOMETHINGS <--- note pluralization
* BaseAssembly = Assembly for your calling project-NOT this DLL
* (if this is in a dll)...
*
* This method is given a table name (plural), and returns an instance
* of that Model' class (singular)... Failing that, returns null.
*/
public object CreateInstanceOf(string DbTableName, Assembly BaseAssembly)
{
string className = String.Empty;
string baseClassName = String.Empty;
string trimmedClassName = String.Empty;
string qualifiedAssemblyName = String.Empty;
try
{
/**********************
*
* Part 1 - just get the details on a matching class...
*
*/
foreach (var t in BaseAssembly.GetTypes())
{
if (((String)t.Namespace == null) || (!t.Namespace.Contains("Models"))) // adjust to suit (I'm in MVC here)
{
// Type is not in Models namespace... skipping
continue; // just looking for classes in the Models namespace (MVC)
}
foreach (var cat in t.CustomAttributes)
{
foreach (var car in cat.ConstructorArguments)
{
if (car != null)
{
t.Name, cat.ToString(), car.ToString());
char[] charsToTrim = { '"', ' ' }; // weird how there are actual quotes in the string...
string trimmedCar = car.ToString().Trim(charsToTrim);
if (trimmedCar == DbTableName)
{
// we have a winner!
qualifiedAssemblyName = t.AssemblyQualifiedName;
baseClassName = trimmedCar;
trimmedClassName = (t.Namespace + "." + trimmedCar).Trim(charsToTrim);
break;
} else
{
// nothing to see here, move along...
}
}
}
}
}
/**********************
*
* Part 2 - create the class with this info...
*
*/
if ((trimmedClassName != null) && (trimmedClassName.Length > 0))
{
Type tipe = Type.GetType(qualifiedAssemblyName);
AssemblyName an = BaseAssembly.GetName();
char[] charsToTrim = { '"', ' ' };
string trimmedManModName = BaseAssembly.ManifestModule.Name.ToString().Trim(charsToTrim);
var result = Activator.CreateInstance(
tipe
);
return result;
} else
{
throw new ArgumentNullException();
}
}
catch (Exception ex)
{
return null;
}
}
person
Yumi Koizumi
schedule
19.11.2016