まず、アプリケーションディクショナリの代わりにキャッシュの使用を検討することをお勧めします。特に、キャッシュされたデータはある時点で期限切れになるためです。この質問を見てください
また、MVCはコントローラー内のすべてのパブリックメソッドを公開するため、コントローラーメソッドがビューによってのみ使用されるかどうかを検討してください。URLを使用してこのメソッドに自由にアクセスしたくない場合は、[NonAction]
属性を設定します。
System.Web.HttpContext.Current
エラーに関しては、コントローラーのCachedSlidesプロパティの実装を通じて、アプリケーションオブジェクトにアクセスすることでエラーを修正する簡単な方法があります。
ビューにSliderControllerの新しいインスタンスを作成するときに、ControllerContextを設定することもできます。そうすれば、コントローラーのHttpContextは、CachedSlidesプロパティにアクセスするときにnullを返しません。
@{
var sliderController = new LevEl.Controllers.Admin.SliderController();
sliderController.ControllerContext = new ControllerContext(ViewContext.RequestContext, sliderController);
var sliderModel = sliderController.GetSlides();
}
これらすべてのビューを処理する基本コントローラークラスを用意することが理にかなっている場合は、コントローラーの取得がよりクリーンになります。ViewContext.Controller
インスタンスをその基本コントローラークラスとしてキャストする必要があります。
var sliderController = ViewContext.Controller as BaseSlideController;
var sliderModel = sliderController.GetSlides();
ただし、これらのアプローチはすべて、そのコードをすべてのビューに追加する必要があります。スライドコレクションにアクセスする必要があるすべてのビューの基本クラスを用意することを検討してください。
public abstract class SlidesEnabledView<T> : WebViewPage<T>
{
private IEnumerable<Slide> _slides;
protected IEnumerable<Slide> Slides
{
get
{
if(_slides == null)
{
var sliderController = ViewContext.Controller as BaseSlideController;
_slides = sliderController.GetSlides();
}
return _slides;
}
}
}
次に、ビューに@inheritsタグを追加して、作成した基本クラスから継承します(@inheritsを使用する場合、@ modelも使用できないため、@inheritsで汎用ベースをバインドしますビュータイプti具体的なモデルタイプ)。SlidesEnabledView
これにより、ベースビュークラスで定義されたプロパティを使用できるようになります。SlidesEnabledViewの名前空間がLevel.ViewClasses.Adminであるとすると、これは次のようになります。
@inherits Level.ViewClasses.Admin.SlidesEnabledView<SomeViewModelClass>
Number of Slides: @Slides.Count()
ISlidesProvider
最後に、サイトでDIを使用していて、DependencyResolverを構成している場合は、スライドを取得するためのロジックをとのような独自のクラスとインターフェイスに移動することを検討できますCachedSlideProvider
。次に、抽象ビュークラスでプロパティインジェクションを使用して、Slidesプロパティで使用されるISlidesProviderのインスタンスを取得できます。
public interface ISlidesProvider
{
IEnumerable<Slide> GetSlides();
}
public class CachedSlideProvider : ISlidesProvider
{
//you will need a constructor that takes the "Context" object, which will be injected into this class
public IEnumerable<Slide> GetSlides()
{
if (CachedSlides == null)
CachedSlides = Context.Slides.OrderBy(p => p.SortOrder).ToArray();
return CachedSlides;
}
private IEnumerable<Slide> CachedSlides
{
get { return System.Web.HttpRuntime.Cache[SlidesCacheKey] as IEnumerable<Slide>; }
set { System.Web.HttpRuntime.Cache[SlidesCacheKey] = value; }
}
}
public abstract class SlidesEnabledView<T> : WebViewPage<T>
{
private IEnumerable<Slide> _slides;
protected IEnumerable<Slide> Slides
{
get
{
if(_slides == null)
{
_slides = this.SlidesProvider.GetSlides();
}
return _slides;
}
}
//This property will be set by your DI container
//You have configured ISlidesProvider to be resolved as CachedSlidesProvider in the DI container
//You have also implemented and registered an MVC DependencyResolver that uses your DI container
//For example, using Microsoft Unity you could set this attribute
[Dependency]
public ISlidesProvider SlidesProvider { get; set; }
}
パラメーターなしのコンストラクターを使用してコントローラーのインスタンスを作成していたため、サイトでDIを使用していない可能性があります。したがって、このDIオプションは、この特定の問題を解決するためだけに少しやり過ぎかもしれません。