0

Castle Windsor と依存性注入を使用して ASP.NET MVC プロジェクトを作成しようとしています。次のことを期待して、すべてが正常に機能しています。

Global.asax

Container = new WindsorContainer();
Container.Install(new WebInstaller(), new LoggingInstaller());

var customControllerFactory = new CustomControllerFactory(Container);
ControllerBuilder.Current.SetControllerFactory(customControllerFactory);

Castle クラスを登録するための Web インストーラー:

string connectionStr = GetConnectionString("MainModel");
container.Register(Component.For(typeof(MainModelContainer)).DependsOn(new { 
          connectionString = connectionStr }).LifestylePerWebRequest());
container.Register(Classes.FromAssemblyContaining<MemberQueries>().InNamespace("User.EF.Queries").WithService.DefaultInterfaces().LifestylePerWebRequest());
container.Register(Classes.FromAssemblyContaining<HomeController>().BasedOn<IController>().LifestylePerWebRequest());

//PROBLEM that doesn't work
container.Register(Classes.FromAssemblyContaining<HomeController>().BasedOn<IAddMessage>().LifestylePerWebRequest());

ホームコントローラー

public IAddMessage AddMessage { get; set; }
private readonly IMemberQueries _memberContract;

public HomeController(IMemberQueries memberContract)
{
  _memberContract = memberContract;
}

public ActionResult Index()
{
   //PROBLEM AddMessage is Null and is not resolved automaticaly
   AddMessage.Add("Test", MessageTypes.message);
   return View("Index");
}

IAddMessage の実​​装

public class CustomMessage : IAddMessage
{
    private IController Controller { get; set; }

    public CustomMessage(IController controller)
    {
        Controller = controller;
    }

    public void Add(string text, MessageTypes messageTypes)
    {
        //TODO
    }
}

IAddMessage インターフェイス

public interface IAddMessage
{
    void Add(string text, MessageTypes messageTypes);
}

問題は、コンテナーが CustomMessage コンストラクターの IController 依存関係を解決できないため、IAddMessage プロパティが null であることです。しかし、この問題を解決する方法がわかりません。

Castle コンテナーの内部エラー メッセージには、次のように表示されます。

このコンポーネントの一部の依存関係を静的に解決できませんでした。'User.Web.UI.Helper.Messages.CustomMessage' は次の依存関係を待機しています: - 登録されていないサービス 'System.Web.Mvc.IController'。

私はウェブをよく見ましたが、私の問題に対する実用的なヒントや解決策が見つかりません。

4

2 に答える 2

1

問題は、IController 依存関係を登録していないことです。次の行でそれを行ったと考えていると思います。

container.Register(Classes.FromAssemblyContaining<HomeController>().BasedOn<IController>().LifestylePerWebRequest());

そうしているように見えるかもしれませんが、実際に行っているのは、このインターフェースを実装するすべてのクラスを登録することです。したがって、コンテナに を要求するとHomeController、それを解決する方法がわかりますが、 IController を要求すると、HomeControllerやその他のコントローラを作成するかどうかがわかりません。

おそらく必要なのは、現在アクティブなコントローラーです。これを行うには、おそらく CustomControllerFactory から継承し、作成したコントローラーをリクエスト スコープに保存する必要があります。その後、CustomMessage クラス内のリクエスト スコープから取得できます。

次のスレッドでその方法を確認できます: Asp.net mvc 3- 現在のコントローラー インスタンスを取得します (名前だけでなく)

于 2013-08-30T23:53:51.710 に答える
0

Kenneth の助けを借りて、次のようなソリューションを見つけました。

private const string CurrentControllerIndexName = "CurrentControllerItem";

protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
   if (controllerType == null)
   {
       throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", requestContext.HttpContext.Request.Path));
        }

        var controller = (IController)this._container.Resolve(controllerType);
        //I am Using the Context not the current Session!
        if(HttpContext.Current.Items.Contains(CurrentControllerIndexName))
        {
            HttpContext.Current.Items.Remove(CurrentControllerIndexName);
        }

        HttpContext.Current.Items.Add(CurrentControllerIndexName, controller);

        return controller;
    }

public static IController GetCurrentController()
{
    if(HttpContext.Current.Items.Contains(CurrentControllerIndexName))
    {
        return (IController) HttpContext.Current.Items[CurrentControllerIndexName];
    }

    throw  new Exception("No Controller found in the Current HttpContext");
 }

「DefaultControllerFactory」を拡張し、HttpContext を使用して、現在の使用済みコントローラーを現在の HttpRequest に格納しています。これは現在正常に機能しています。

CustomMessage は次のようになります。

public class CustomMessage : IAddMessage
{
   public CustomMessage()
   {
   }

   public void Add(string text, MessageTypes messageTypes)
   {
       Controller controller = (Controller)CustomControllerFactory.GetCurrentController();
       //TODO
   } 
}

そして私のキャッスルレジスター

...
container.Register(Classes.FromAssemblyContaining<HomeController>().BasedOn<IController>().LifestylePerWebRequest());
container.Register(Component.For<IAddMessage>().ImplementedBy<CustomMessage>());
...

これで問題なく動作します。

于 2013-08-31T09:43:23.900 に答える