Есть несколько проблем.
Во-первых, ваша TableScript
регистрация:
builder.RegisterType<TableScript>()
.As(typeof(Script<>))
.InstancePerLifetimeScope();
builder.RegisterType<TableScript>()
.As(typeof(IScript<>))
.InstancePerLifetimeScope();
Вы пытаетесь зарегистрировать закрытый универсальный как открытый универсальный . Если подумать о том, что это значит, это все равно, что сказать «TableScript
может разрешить любой T
для Script<T>
и IScript<T>
». Например, я вижу TableScript : Script<TableScriptOptions>
- то, что говорит открытая общая регистрация, должно так или иначе работать на Script<IntegerScriptOptions>
или что-то еще, что могло бы попасть в эти угловые скобки.
Вместо этого зарегистрируйте его как закрытое универсальное. И я бы порекомендовал сделать это при одной и той же регистрации, иначе вы можете получить два разных экземпляра из TableScript
за область действия в зависимости от того, какая служба разрешена.
builder.RegisterType<TableScript>()
.As<Script<TableScriptOptions>>()
.As<IScript<TableScriptOptions>>()
.InstancePerLifetimeScope();
Далее разрешение IScript<T>
:
scope.Resolve(typeof(IScript<>)) as IScript<object>;
Думайте о Resolve
как о new
. Если вы не можете использовать new
или Activator.CreateInstance
вместо него (в основном), то это не сработает. Например, вы не можете сделать это:
// This isn't a thing
new Script<>();
Вы также не можете поместить открытый универсальный объект в конструктор объекта, например, так:
public class MyClass
{
// This also isn't a thing
public MyClass(IScript<> script) { /* ... */ }
}
Вы не можете создать новый общий дженерик. Компилятор должен знать, что T
находится в Script<T>
. По тому же признаку, вы не можете разрешить открытый универсальный. Это не имеет смысла. Вы должны разрешить закрытый универсальный.
scope.Resolve<IScript<TableScriptOptions>>();
Если вы действительно хотите использовать рефлексию, вам все равно нужно сделать ее закрытой.
var script = typeof(IScript<>);
var options = typeof(TableScriptOptions);
var closed = script.MakeGenericType(new Type[] { options });
scope.Resolve(closed);