Autofac с открытыми дженериками и типом, указанным во времени выполнения

SVD может быть понят от геометрического смысла для квадратных матриц как преобразование на векторе.

Считают квадратную матрицу n x n M умножением вектора v для создания выходного вектора w:

w = M*v

сингулярное разложение M является продуктом трех матриц M=U*S*V, таким образом w=U*S*V*v. U и V ортонормированные матрицы. С точки зрения геометрического преобразования (реагирующий на вектор путем умножения его), они - комбинации вращений и отражений, которые не изменяют длину вектора, который они умножают. S является диагональной матрицей, которая представляет масштабирование или сплющивание с различными масштабными коэффициентами (диагональные термины) вдоль каждой из n осей.

Так эффект лево-умножения вектора v матрицей M должен вращаться/отражать v на M ортонормированный фактор V, затем масштабировать/раздавить результат диагональным фактором S, затем вращаться/отражать результат на M ортонормированный фактор U.

Одна причина, SVD желателен с числовой точки зрения, состоит в том, что умножение ортонормированными матрицами является обратимым, и чрезвычайно стабильный операция (число условия равняется 1). SVD получает любую плохо обусловленность в диагональной матрице масштабирования S.

7
задан Peter Lillevold 8 October 2009 в 08:11
поделиться

2 ответа

Это, безусловно, возможно с Autofac. Во время «регистрации» вы в основном делаете следующее:

  1. Зарегистрируйте открытый универсальный тип (PassThroughFlattener <>)
  2. Зарегистрируйте любые конкретные типы (AddressFlattener)
  3. Зарегистрируйте метод, который можно использовать для разрешения IFlattener на основе входного объекта

Во «время разрешения» вы должны:

  1. Разрешить метод
  2. Вызвать метод с входными параметрами, чтобы разрешить реализацию IFlattener

Вот (надеюсь) рабочий пример:

var openType = typeof(IFlattener<>);

var builder = new ContainerBuilder();
builder.RegisterGeneric(typeof(PassThroughFlattener<>)).As(openType);
builder.Register<AddressFlattener>().As<IFlattener<Address>>();
builder.Register<Func<object, IFlattener>>(context => theObject => 
    {
        var closedType =
            openType.MakeGenericType(theObject.GetType());
            return (IFlattener) context.Resolve(closedType,
                new PositionalParameter(0, theObject));
    });
var c = builder.Build();

var factory = c.Resolve<Func<object, IFlattener>>();

var address = new Address();
var addressService = factory(address);

Assert.That(addressService, Is.InstanceOfType(typeof(AddressFlattener)));

var anything = "any other data";
var anyService = factory(anything);

Assert.That(anyService, Is.InstanceOfType(typeof(PassThroughFlattener<string>)));
10
ответ дан 6 December 2019 в 15:24
поделиться

Если вы не знаете тип до времени выполнения, вы можете создать его с помощью MakeGenericType:

var addressFlattener = _container.Resolve(typeof(IFlattener<>).MakeGenericType(typeof(Address)));
4
ответ дан 6 December 2019 в 15:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: