3

Autofac を使用してコントローラーにサービスを挿入する MVC Web アプリがあります。

問題:サービスでプロパティ インジェクションを実行しようとしましたが、失敗しました (プロパティは常に null です)。

私が期待すること: プロパティが Autofac によって適切に (null ではなく) 初期化されることを期待しています。

例:

  • AliasesService を IAliasesService としてコントローラーに挿入しようとしています。
  • AliasesService は MailService に依存します。
  • MailService は AliasesService のプロパティです。
  • AliasesService は適切にインスタンス化され、MyController に渡されます。
  • MailService が適切にインスタンス化されておらず、AliasesService のプロパティに設定されていません

コントローラ:

public class MyController: Controller
{
    private IAliasesService AliasesService { get; set; }

    public MyController(IAliasesService aliasesService)
    {
        AliasesService = aliasessService;
    }

    public ActionResult Index()
    {
        var model = aliasesService.GetUserRoles();

        return View();
    }
}

Global.asax:

var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired();

builder.RegisterType<MailService>().As<IMailService>();
builder.RegisterType<AliasesService>().As<IAliasesService>().PropertiesAutowired();

var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

AliasesService:

public class AliasesService
{
     public IMailService MailService { get; set; }

     public Dictionary<int,string> GetUserRoles()
     {
          MailService.SendMail("method GetUserRoleshas been called");
          return null;
     }
}

言及する価値があります:

  • コントローラーのプロパティ インジェクションを実行しようとすると、期待どおりに動作します
  • コンストラクター注入は機能しますが、プロパティ注入が必要です。

成功しなかった他のこと:

1

builder.RegisterType<MailService>()
       .As<IMailService>();
builder.Register(c => new AliasesService() 
       { 
           MailService = c.Resolve<IMailService>() 
        })
       .As<IAliasesService>();

2

builder.RegisterType<MailService>()
       .As<IMailService>();
builder.RegisterType<AliasesService>()
       .WithProperty("MailService", new MailService())
       .As<IAliasesService>();

最小限の例:

using Autofac;

namespace ConsoleApplication1
{
    public interface IBar
    {    
    }

    public class Bar: IBar
    {
        public string Text { get; set; }

        public Bar()
        {
            Text = "Hello world!";
        }
    }

    public interface IFoo
    {
    }

    public class Foo: IFoo
    {
        public IBar Bar { get; set; }
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = new ContainerBuilder();

            builder.RegisterType<Bar>().As<IBar>();
            builder.RegisterType<Foo>().As<IFoo>().PropertiesAutowired();

            var container = builder.Build();

            var foo = container.Resolve<IFoo>();
        }
    }
}

代替ソリューション:

最小限の例では、Autofac は機能しますが、コントローラーのコンテキストでは、期待どおりに機能させることができなかったため、時間を無駄にしたため、使用を断念しました。今のところ、Castle Windsor を使用していますが、必要なことはすべて実行してくれます。サポートに感謝します。

4

3 に答える 3

1

最小限のコード サンプルでは、​​プロパティBarは登録されていない型で宣言Barされています。Autofacで解決できるようにするには、宣言されたプロパティの型を登録する必要があります。プロパティのタイプをに変更するか、としてIBar登録する必要がありますBarBar

public class Foo : IFoo
{
    public IBar Bar { get; set; }
}

また

builder.RegisterType<Bar>().As<Bar>();
于 2015-04-15T17:01:43.620 に答える
1

あなたの最小限の例はうまくいきます.FooはBarインスタンスが注入されて解決します.

あまり役に立ちませんが、問題は別の場所にあります。

于 2015-04-17T09:11:27.653 に答える
0

AliasesService は Interface IAliasesService を実装していないため、あなたの例は間違っていますが、それはタイプミスだと思います。

MAilService の実装がありません。解決できない依存関係がある場合、PropertiesAutowired() は暗黙のうちに失敗します。

だからあなたの問題はおそらくMailServiceにあります

于 2016-01-15T15:48:11.167 に答える