I heve registred two clasess
namespace ExtendedModules.MyExtendedModule
{
public class MyWrapper : ISystemInfoSource, IDisposable
{
public MyWrapper(ILicenceProvider licenceProvider, ISQLConnection connection, IDataSharingOptions dataSharingOptions)
{
}
public bool ManualLoadingConditions
{
get { return _seakeepingSettings != null && Convert.ToBoolean(_seakeepingSettings["ManualLoadingConditions"]); }
}
public bool LicenseValid
{
get { return _licenseValid; }
}
}
}
Secend class
public class MyUi
{
private MyWrapper _wrapper;
private IWaitWindowNavigator _waitNavigator;
public delegate bool CalculateAction(out string message);
public MyUi(MyWrapper wrapper, IWaitWindowNavigator waitNavigator)
{
_wrapper = amarcon;
_waitNavigator = waitNavigator;
}
}
I found old code where we have conditional registering extended module and in this module we have registered some clasess.
For the end of regostering process we had registred class who derived from IStartable interface and we passin to constructor of this class builder object
[MethodImpl(MethodImplOptions.NoInlining)]
public void Register(ContainerBuilder builder)
{
var optionsConnection = new ResolvedParameter(
(p, c) => p.ParameterType == typeof(ISQLConnection),
(p, c) => c.ResolveNamed<ISQLConnection>("options"));
builder.RegisterType<MyWrapper>().WithParameter(optionsConnection).SingleInstance().As<ISystemInfoSource>().AsSelf();
builder.RegisterType<MyUi>().SingleInstance();
builder.RegisterType<ValidLicenseRegistrations>().WithParameter(new TypedParameter(typeof(ContainerBuilder), builder)).SingleInstance().As<IStartable>();
}
And in this cass we conditionally registering other classess an for end of this process we had using Update(..)
public class LicenseRegistrations : IStartable
{
public LicenseRegistrations(IComponentContext context, MyWrapper wrapper, ContainerBuilder builder)
{
if (!wrapper.LicenseValid)
return;
var optionsConnection = AutofacUtils.ResolvedParameter((c) => c.ResolveNamed<ISQLConnection>("options"));
if (wrapper.ManualLoadingConditions)
{
builder.RegisterType<LoadingConditionsVoyageWizardViewModel>().As<IVoyageWizardPage>();
builder.RegisterType<LoadingConditionsWindowNavigator>().SingleInstance();
builder.RegisterType<LoadingConditionsViewModel>();
builder.RegisterType<LoadingConditionsWindow>();
builder.RegisterType<LoadingConditionsDisplayViewModel>().SingleInstance().As<IProfileSection>();
builder.Update(context.ComponentRegistry);
}
}
public void Start()
{
}
}
This old code starts work if i move registration from LicenseRegistrationsclass to MyModule but i need comment conditions
enter image description here
[MethodImpl(MethodImplOptions.NoInlining)]
public void Register(ContainerBuilder builder)
{
var optionsConnection = new ResolvedParameter(
(p, c) => p.ParameterType == typeof(ISQLConnection),
(p, c) => c.ResolveNamed<ISQLConnection>("options"));
builder.RegisterType<MyWrapper>().WithParameter(optionsConnection).SingleInstance().As<ISystemInfoSource>().AsSelf();
builder.RegisterType<MyUi>().SingleInstance();
//builder.RegisterType<ValidLicenseRegistrations>().WithParameter(new TypedParameter(typeof(ContainerBuilder), builder)).SingleInstance().As<IStartable>();
// if (!wrapper.LicenseValid)
// return;
//if (wrapper.ManualLoadingConditions)
//{
builder.RegisterType<LoadingConditionsVoyageWizardViewModel>().As<IVoyageWizardPage>();
builder.RegisterType<LoadingConditionsWindowNavigator>().SingleInstance();
builder.RegisterType<LoadingConditionsViewModel>();
builder.RegisterType<LoadingConditionsWindow>();
builder.RegisterType<LoadingConditionsDisplayViewModel>().SingleInstance().As<IProfileSection>();
//}
}
do you know what I have to do to maintain the conditions ?
And how resolve MyWrapper class during registration classes in Module ?
I heve registred two clasess
namespace ExtendedModules.MyExtendedModule
{
public class MyWrapper : ISystemInfoSource, IDisposable
{
public MyWrapper(ILicenceProvider licenceProvider, ISQLConnection connection, IDataSharingOptions dataSharingOptions)
{
}
public bool ManualLoadingConditions
{
get { return _seakeepingSettings != null && Convert.ToBoolean(_seakeepingSettings["ManualLoadingConditions"]); }
}
public bool LicenseValid
{
get { return _licenseValid; }
}
}
}
Secend class
public class MyUi
{
private MyWrapper _wrapper;
private IWaitWindowNavigator _waitNavigator;
public delegate bool CalculateAction(out string message);
public MyUi(MyWrapper wrapper, IWaitWindowNavigator waitNavigator)
{
_wrapper = amarcon;
_waitNavigator = waitNavigator;
}
}
I found old code where we have conditional registering extended module and in this module we have registered some clasess.
For the end of regostering process we had registred class who derived from IStartable interface and we passin to constructor of this class builder object
[MethodImpl(MethodImplOptions.NoInlining)]
public void Register(ContainerBuilder builder)
{
var optionsConnection = new ResolvedParameter(
(p, c) => p.ParameterType == typeof(ISQLConnection),
(p, c) => c.ResolveNamed<ISQLConnection>("options"));
builder.RegisterType<MyWrapper>().WithParameter(optionsConnection).SingleInstance().As<ISystemInfoSource>().AsSelf();
builder.RegisterType<MyUi>().SingleInstance();
builder.RegisterType<ValidLicenseRegistrations>().WithParameter(new TypedParameter(typeof(ContainerBuilder), builder)).SingleInstance().As<IStartable>();
}
And in this cass we conditionally registering other classess an for end of this process we had using Update(..)
public class LicenseRegistrations : IStartable
{
public LicenseRegistrations(IComponentContext context, MyWrapper wrapper, ContainerBuilder builder)
{
if (!wrapper.LicenseValid)
return;
var optionsConnection = AutofacUtils.ResolvedParameter((c) => c.ResolveNamed<ISQLConnection>("options"));
if (wrapper.ManualLoadingConditions)
{
builder.RegisterType<LoadingConditionsVoyageWizardViewModel>().As<IVoyageWizardPage>();
builder.RegisterType<LoadingConditionsWindowNavigator>().SingleInstance();
builder.RegisterType<LoadingConditionsViewModel>();
builder.RegisterType<LoadingConditionsWindow>();
builder.RegisterType<LoadingConditionsDisplayViewModel>().SingleInstance().As<IProfileSection>();
builder.Update(context.ComponentRegistry);
}
}
public void Start()
{
}
}
This old code starts work if i move registration from LicenseRegistrationsclass to MyModule but i need comment conditions
enter image description here
[MethodImpl(MethodImplOptions.NoInlining)]
public void Register(ContainerBuilder builder)
{
var optionsConnection = new ResolvedParameter(
(p, c) => p.ParameterType == typeof(ISQLConnection),
(p, c) => c.ResolveNamed<ISQLConnection>("options"));
builder.RegisterType<MyWrapper>().WithParameter(optionsConnection).SingleInstance().As<ISystemInfoSource>().AsSelf();
builder.RegisterType<MyUi>().SingleInstance();
//builder.RegisterType<ValidLicenseRegistrations>().WithParameter(new TypedParameter(typeof(ContainerBuilder), builder)).SingleInstance().As<IStartable>();
// if (!wrapper.LicenseValid)
// return;
//if (wrapper.ManualLoadingConditions)
//{
builder.RegisterType<LoadingConditionsVoyageWizardViewModel>().As<IVoyageWizardPage>();
builder.RegisterType<LoadingConditionsWindowNavigator>().SingleInstance();
builder.RegisterType<LoadingConditionsViewModel>();
builder.RegisterType<LoadingConditionsWindow>();
builder.RegisterType<LoadingConditionsDisplayViewModel>().SingleInstance().As<IProfileSection>();
//}
}
do you know what I have to do to maintain the conditions ?
And how resolve MyWrapper class during registration classes in Module ?
Share Improve this question edited Mar 3 at 19:49 Progman 19.7k7 gold badges55 silver badges82 bronze badges asked Mar 3 at 16:29 Paweł UrbańskiPaweł Urbański 156 bronze badges2 Answers
Reset to default 1in my opinion, the closest thing to a solution is this
_container = _builder.Build();
using (var scope = _container.BeginLifetimeScope())
{
using (var scope2 = _container.BeginLifetimeScope(
builder =>
{
var myWrapper = scope.Resolve<MyWrapper>();
builder.RegisterModule(new MyModule3(myWrapper));
})) ;
}
Because this solution properly resolves instance of class MyWrapper which is then passed to the next version of the module MyModule3() as a parameter
public class Module3 : Autofac.Module
{
private MyWrapper _myWrapper;
public Module3(MyWrapper myWrapper)
{
_myWrapper = myWrapper;
}
public void Register(ContainerBuilder builder)
{
if (_myWrapper.ManualLoadingConditions)
{
builder.RegisterType<SomeClasses>().As<ISomeClasses>();
where further registration of classes takes place depending on the condition of the object passed as a parameter. And even though theoretically this solution should work, I don't see its effects when I start the application. Thats mean additional elements that should be the result of registering classes in MyModule3() do not appear in application
Classes registered in Module3() are not visible in the main container. So what should I do ?
You didn't list any package versions, but my guess is you're looking at some pretty old code because we marked ContainerBuilder.Update
as Obsolete
back in 2016 and it was entirely removed from Autofac in 2020.
There was a pretty big discussion thread talking about alternatives to Update
that can give you ideas on what to do. Since applications are all different, there's no "one size fits all" answer, which is why telling you exactly how to fix this in your specific application isn't really possible. I could come up with one solution, and invariably there will be a "but I have XYZ" and then we'd spend the next several weeks iterating over design idea after design idea and... honestly, I'm happy to help, but I don't have time for free consulting at that level.
What I will do is provide you with some common solutions that may help spark some ideas for you.
- Two separate containers: Sometimes folks need to have an "application bootstrap container" where there's just enough registered to build the set of things to get the app started; and then a second container that actually gets used during the application runtime. It may mean that you have to register some things into both containers separately. Definitely do not try to "chain" two containers together because you want to "optimize" something and try not to register both containers. Seriously, that way lies madness.
- App setup in root container, app runtime in child scope: You can register new services in a child lifetime scope when it's created. That means you could figure out if you need to add things to the container and conditionally register those into a child scope. Your app would then use that child scope as the "root" during runtime. Further, that would allow you to potentially drop that child scope and re-create/rebuild it if you need to work with plugins or other dynamic things.
- Try to avoid
IStartable
. Yeah, it's convenient, but it gets folks thinking about trying to tie all the app startup orchestration to container building, and that's not what the container is for. Separate the "do I need to register this" logic away fromIStartable
and the container build process so you can more clearly see when things need to be registered and how.
Again, take some time to read through that thread I mentioned because lots of ideas were tossed around in there.
Hopefully this at least unblocks you. As I mentioned, there's no "one right solution" and I will not be able to come back here and iterate over solutions in the comments, so do what you can with the new information provided and if you are still hitting a problem, ideally it's a far more specific problem for which you can open a new question with a better repro using newer package versions.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745083477a4610266.html
评论列表(0条)