c# - Autofac how to replace Obsolete Update() - Stack Overflow

I heve registred two clasessnamespace ExtendedModules.MyExtendedModule{public class MyWrapper : ISyst

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 badges
Add a comment  | 

2 Answers 2

Reset to default 1

in 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 from IStartable 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

相关推荐

  • c# - Autofac how to replace Obsolete Update() - Stack Overflow

    I heve registred two clasessnamespace ExtendedModules.MyExtendedModule{public class MyWrapper : ISyst

    16小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信