Skip to content

Using DI for FluentFTP in ASP.NET Core, NET #1199

Closed

Description

@kostazol

**FluentFTP Version: 45.0.3

Framework: .NET 7

Hello. Do you have some best practices for using Fluent FTP with DI? May be FluentFTP need client factory as http client https://learn.microsoft.com/en-us/dotnet/core/extensions/httpclient-factory ?

Activity

  1. robinrodricks commented on Feb 17, 2023

    @robinrodricks
    Owner
  2. kostazol commented on Feb 17, 2023

    @kostazol
    Author

    May you send some micro example?
    If I use IAsyncFtpClient via DI into constructor, how I will set ip address, login and password?

  3. robinrodricks commented on Feb 17, 2023

    @robinrodricks
    Owner

    AsyncFtpClient implements IAsyncFtpClient, cant you use that?

    Manually set the properties of AsyncFtpClient once your DI container passes a concrete instance...

    Like

    MyOtherClass(IAsyncFtpClient client){
        client.Host = ..
        client.Credentials = ...
        client.Connect();
    }
    

    And then register the type:

    myDIFramework.Register<IAsyncFtpClient,AsyncFtpClient>();
    
  4. kostazol commented on Feb 17, 2023

    @kostazol
    Author

    Thank you! But If in the future you will add factory it will be cool.

  5. robinrodricks commented on Feb 17, 2023

    @robinrodricks
    Owner

    Can you give an example of what you are looking for?

  6. kostazol commented on Feb 17, 2023

    @kostazol
    Author

    https://learn.microsoft.com/en-us/dotnet/core/extensions/httpclient-factory

    If we see usually variant it will be the same as using interface and init client in the constructor. But we have named client or typed client and can set client on start application and use it in other places. It will very help if for initialization we have more parameters than ip, login, password.
    When start it:

    services.AddHttpClient("testClient", client =>
                    {
                        client.BaseAddress = new Uri(url);
                    })
                    .AddHttpMessageHandler<AuthSystemUserTokenToHeaderHandler>(); 
    

    When need client:
    var client = _clientFactory.CreateClient("testClient");

  7. robinrodricks commented on Feb 17, 2023

    @robinrodricks
    Owner

    See even in this example, you are manually setting properties on client, so you can do the same with FluentFTP client. Nothing is stopping you.

    Or are you asking for a Factory object and IFactory interface??

    And Factory would have methods to create FtpClient and AsyncFtpClient??

  8. kostazol commented on Feb 21, 2023

    @kostazol
    Author

    Or are you asking for a Factory object and IFactory interface??

    And Factory would have methods to create FtpClient and AsyncFtpClient??

    Yes, I about a factory with methods to create FtpClient and AsyncFtpClient. And also I want to set clients parameters at start (as my example) and create tunned clients from any place.

  9. parthvnp commented on Feb 23, 2023

    @parthvnp

    I can work on adding client factories if needed! @kostazol I think the reason HttpClientFactory exists is because the usage of HttpClient is quite not intuitive as the IDisposable behaviour doesn't conform to with the rest of the framework.

  10. robinrodricks commented on Feb 23, 2023

    @robinrodricks
    Owner

    @parthvnp Go ahead please!

  11. parthvnp commented on Feb 28, 2023

    @parthvnp

    @robinrodricks @kostazol Here is the spec for design of IAsynFtpClientFactory. Would appreciate feedback and suggestions before I start implementing it. The design inspiration for this Quartz.NET and Microsoft.Extensions.Http.

    FTP Client Factory

    • The goal of IAsynFTPClientFactory is to create named (and later typed) FTP clients that can be configured at application start and reused throughout the application. Multiple clients with different configuration can be added and later injected as dependencies. In essence the goal is here: Configure once, use everywhere.
    • FTP Clients are configured by settings up appropriate values for Action<IAsynFTPClientConfigurator>. This interfaces exposes values for settings up FTP Client either by providing FTPConfig instance or by providing the most important properties required to configure the FTP Client. Additionally, the client can also be configured using sections from appsettings.json file if desired.
    • An IAsyncFTPClientBuilder is used to build IAsynFTPClient using the options provided in IAsynFTPClientConfigurator. This class is used internally to build an FTP Client every time Create is called on the factory.
    • Each new call to Create creates a new FTP Client. The onus of disposing the FTP client is on the user of the factory. I am still not sure on this behaviour. For example, it is possible for the factory to manage the lifetime, but this requires the client to know about this implicit behaviour.
    • Possible exceptions can arise if the client wants to
    1. Create a named FTP Client has not been registered.
    2. FTP client with the same name is already registered.
    3. Configuration fails because FTPConfig validation fails. This error won't be surfaced till a call to Create is made.

    Minimal examples of the FTP Client Factory API

    // create a named FTP Client
    IAsyncFTPClientFactory ftpFactory = new DefaultAsyncFTPClientFactory("ftp_client_v1", options => {
       // setup FtpConfig options here
    });
    
    
    // in controller for example
    
    public Example: ControllerBase {
        private IAsyncFTPClientFactory _factory;
        public Example(IAsynFTPClientFactory factory){
            _factory = factory;
        }
    
        // using the factory to create FTP Client to upload files
        public UploadFile(){
            var client = _factory.Create("ftp_client_v1"); // throws not registered expection if the named client has not been registered
            client.uploadFile(@"D:\Github\FluentFTP\README.md", "/public_html/temp/README.md);
        }
    }
  12. kostazol commented on Feb 28, 2023

    @kostazol
    Author

    Everything, is great. But about "The onus of disposing the FTP client is on the user of the factory. I am still not sure on this behaviour." as I know in Microsoft.Extensions.Http usually factory control disposing. I don't know details but it helps control "connection pool" ( HTTP persistent connection ), some discution:
    https://stackoverflow.com/questions/54597303/should-i-cache-and-reuse-httpclient-created-from-httpclientfactory

  13. robinrodricks commented on Feb 28, 2023

    @robinrodricks
    Owner

    @parthvnp Sounds good, you have my blessing to go ahead!

  14. FanDjango commented on Mar 21, 2023

    @FanDjango
    Collaborator
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      ⌂ 换网址