В любой ситуации, когда допустимо, чтобы свойство десериализации было отмечено как внутреннее, есть замечательно простое решение, которое вообще не зависит от атрибутов. Просто пометьте свойство как внутренний get, но public set:
public class JsonTest {
public string SomeProperty { internal get; set; }
}
Это приведет к правильной десериализации с использованием настроек / resolvers / etc., Но свойство лишено из сериализованного вывода.
Обновление: Мой первоначальный ответ был написан до выпуска .NET Framework 4 (вместе с Lazy
) , а другой ответ, хотя и немного более современный, все еще немного устарел. Я оставляю свой исходный ответ ниже на тот случай, если кто-то застрял на более старой версии, но не советовал бы использовать ее с последней версией Ninject или .NET.
Ninject Factory Extension - это современный способ сделать это. Он автоматически подключит любые аргументы или свойства. Для этого вам не нужна отдельная привязка - просто настройте свои службы обычным образом, а расширение сделает все остальное.
К вашему сведению, это же расширение может также подключать настраиваемые заводские интерфейсы или аргументы Func
. Разница в том, что они каждый раз будут создавать новый экземпляр, так что на самом деле это фабрика, а не просто ленивое создание.Просто указываю на это, потому что в документации это не совсем ясно.
Как правило, «полное построение графа объектов» не должно быть настолько дорогостоящим, и если в класс внедряются зависимости, которые он может не использовать, это, вероятно, хороший признак того, что у класса слишком много обязанностей.
На самом деле это не ограничение Ninject как такового - если подумать, на самом деле невозможно иметь «ленивую зависимость», если только (а) внедряемая зависимость сама не является ленивым загрузчиком, например Lazy
класс в .NET 4 или (б) все свойства и методы зависимости используют отложенное создание экземпляров. Что-то нужно ввести туда.
Вы можете выполнить (а) относительно легко, используя интерфейс поставщика , привязку метода (изд.: Ninject не поддерживает открытые универсальные шаблоны с привязками поставщиков) и привязку открытого универсального шаблона. тип. Предполагая, что у вас его нет.NET 4, вам придется создать интерфейс и реализацию самостоятельно:
public interface ILazy<T>
{
T Value { get; }
}
public class LazyLoader<T> : ILazy<T>
{
private bool isLoaded = false;
private T instance;
private Func<T> loader;
public LazyLoader(Func<T> loader)
{
if (loader == null)
throw new ArgumentNullException("loader");
this.loader = loader;
}
public T Value
{
get
{
if (!isLoaded)
{
instance = loader();
isLoaded = true;
}
return instance;
}
}
}
Затем вы можете привязать весь ленивый интерфейс - так что просто привяжите интерфейсы как обычно:
Bind<ISomeService>().To<SomeService>();
Bind<IOtherService>().To<OtherService>();
И привяжите ленивый интерфейс, используя открытые дженерики, к лямбда-методу:
Bind(typeof(ILazy<>)).ToMethod(ctx =>
{
var targetType = typeof(LazyLoader<>).MakeGenericType(ctx.GenericArguments);
return ctx.Kernel.Get(targetType);
});
После этого вы можете ввести аргументы / свойства ленивой зависимости:
public class MyClass
{
[Inject]
public MyClass(ILazy<ISomeService> lazyService) { ... }
}
Это не сделает всю операцию ленивой - Ninject все равно придется фактически создать экземпляр LazyLoader
, но любые зависимости второго уровня ISomeService
не будут загружены, пока MyClass
не проверит значение
этого lazyService
.
Очевидным недостатком является то, что ILazy
не реализует сам T
, поэтому MyClass
должен быть написан так, чтобы принимать ленивые зависимости, если вы хотите преимущество ленивой загрузки. Тем не менее, если создание определенной зависимости чрезвычайно дорого, это будет хорошим вариантом. Я почти уверен, что у вас будет эта проблема с любой формой DI, любой библиотекой.
Насколько мне известно, единственный способ сделать (b) без написания кучи кода - это использовать генератор прокси, например Castle DynamicProxy , или зарегистрировать динамический перехватчик с помощью Ninject Внутренний перехватчик . Это было бы довольно сложно, и я не думаю, что вы захотите пойти по этому пути, если только вам это не понадобится.