Ich versuche, Autofac zu verwenden, um Abhängigkeiten in FluentValidation in einer MVC 4-Anwendung zu injizieren. Ich denke, dass ich die Strategie ausgearbeitet habe, aber ich bleibe dabei, meine Frage nach der Anfrage aus einem Singleton zu lösen.Autofac - wie man Func für ISomething von Singleton löst, wo ISomething ist InstancePerHttpRequest
Hier ist das Szenario: Ich habe einen Validator, der von FluentValidation AbstractValidator abgeleitet ist. Ich habe gelesen, dass FluentValidation-Validatoren am besten als Singletons funktionieren, daher erwartet mein Konstruktor einen Func und speichert diese Factory zur späteren Verwendung. Wenn der Validator verwendet wird, sollte er die gespeicherte Factory nach einem IDataStore fragen, die Instanz für diese Anfrage erstellen und sie verwenden. Das ist die Theorie. Ich möchte https://github.com/robdmoore/UnobtrusiveMVCTechniques danken, die mir bei dieser Lösung geholfen haben. Hier ist der Validator ...
public class SiteAdminViewModelValidator : AbstractValidator<SiteAdminViewModel> {
private readonly Func<IDataStore> _dbFactory;
public SiteAdminViewModelValidator(Func<IDataStore> dbFactory) {
_dbFactory = dbFactory;
RuleFor(model => model.SiteCode).Length(1, 40).Must(BeSpecial);
}
public bool BeSpecial(string siteCode) {
var db = _dbFactory();
List<Stuff> stuffs = db.All<Stuff>().ToList();
return true;
}
}
Wenn jemand mich zu einem Arbeitsbeispiel zeigen kann, was ich versuche zu erreichen, das wäre toll, aber ich würde auch die Lösung für dieses besondere Stück wissen, von Autofac Trickiness.
Hier ist meine Validator Registrierung ...
public class FluentValidatorModule : Module {
protected override void Load(ContainerBuilder builder) {
base.Load(builder);
builder.RegisterType<AutofacValidatorFactory>().As<IValidatorFactory>().SingleInstance();
var validators = AssemblyScanner.FindValidatorsInAssembly(System.Reflection.Assembly.GetExecutingAssembly());
validators.ToList().ForEach(v => builder.RegisterType(v.ValidatorType).As(v.InterfaceType).SingleInstance());
}
}
Hier ist meine Anmeldung für die Fabrik IDataStore ist ...
builder.RegisterType<SuperDB>().As<IDataStore>().InstancePerHttpRequest();
builder.Register<Func<IDataStore>>(c => {
var context = c.Resolve<IComponentContext>();
return context.Resolve<IDataStore>;
});
Hier ist der Fehler, den ich immer bin, wenn mein Validator für eine IDataStore fragt auf die Zeile - var db = _dbFactory();
Kein Rahmen mit einem Tag Matching ‚AutofacWebRequest‘ ist sichtbar von dem Bereich, in dem die Instanz angefordert wurde. Dies zeigt im Allgemeinen , die eine Komponente registriert als pro-HTTP-Anforderung wird durch eine SingleInstance() Komponente (oder ein ähnliches Szenario.) Unter der Web- Integration immer anfordern Abhängigkeiten von der DependencyResolver.Current oder ILifetimeScopeProvider.RequestLifetime, angefordert wird niemals aus dem Container selbst.
... was ich genau dann bekommen habe, als ich es vor dem Schreiben meiner eigenen Werksregistrierung - der Func-Registrierung - ausprobiert habe. Vom Lesen verschiedener Antworten bis zu ähnlichen Fragen sah es so aus, als ob das, was ich oben habe, funktionieren sollte, weil ich dachte, dass ich nun den Func auflösen würde, um den aktuellen Resolver zu bekommen.
Jede Hilfe wird sehr geschätzt.
Das funktioniert! Vielen Dank. Ich bin neu in Autofac. Kann ich nur eine kurze Erläuterung zur Registrierung des Builders erhalten.RegisterInstance (PerHttpSafeResolve [IDataStore]()); Linie? Das heißt also: "Wann immer jemand nach einem Func [IDataStore] fragt, verwenden Sie diese Methode, um ihnen einen zu geben"? –
Siehe meine Bearbeitung - ich werde versuchen, es zu erklären – Felix
Nizza !! Diese Technik ist erstaunlich. Ich liebe es. So sehr habe ich einen Blogbeitrag geschrieben: http://robdmoore.id.au/blog/2013/03/23/resolving-request-scoped-objects-into-a-singleton-with-autofac/. Wenn Sie selbst einen Blog haben, lassen Sie es mich wissen und ich verlinke ihn anstelle Ihres SO-Benutzers. –