10

Làm cách nào để mọi người cấu trúc mã của họ khi sử dụng thư viện không quốc tịch C#?Thư viện máy trạng thái không quốc tịch - cách thích hợp để cấu trúc?

https://github.com/nblumhardt/stateless

Tôi đặc biệt quan tâm đến cách quan hệ này với phụ thuộc tiêm, và một cách tiếp cận đúng đắn về trách nhiệm và layering một cách chính xác.

cấu trúc hiện tại của tôi liên quan đến việc sau đây:

public class AccountWf 
{ 
    private readonly AspNetUser aspNetUser; 

    private enum State { Unverified, VerificationRequestSent, Verfied, Registered } 
    private enum Trigger { VerificationRequest, VerificationComplete, RegistrationComplete } 

    private readonly StateMachine<State, Trigger> machine; 

    public AccountWf(AspNetUser aspNetUser, AccountWfService userAccountWfService) 
    { 
     this.aspNetUser = aspNetUser; 

     if (aspNetUser.WorkflowState == null) 
     { 
      aspNetUser.WorkflowState = State.Unverified.ToString(); 
     } 

     machine = new StateMachine<State, Trigger>(
     () => (State)Enum.Parse(typeof(State), aspNetUser.WorkflowState), 
     s => aspNetUser.WorkflowState = s.ToString() 
     ); 

     machine.Configure(State.Unverified) 
     .Permit(Trigger.VerificationRequest, State.VerificationRequestSent); 

     machine.Configure(State.VerificationRequestSent) 
     .OnEntry(() => userAccountWfService.SendVerificationRequest(aspNetUser)) 
     .PermitReentry(Trigger.VerificationRequest) 
     .Permit(Trigger.VerificationComplete, State.Verfied); 

     machine.Configure(State.Verfied) 
     .Permit(Trigger.RegistrationComplete, State.Registered); 

    } 

    public void VerificationRequest() 
    { 
     machine.Fire(Trigger.VerificationRequest); 
    } 

    public void VerificationComplete() 
    { 
     machine.Fire(Trigger.VerificationComplete); 
    } 

    public void RegistrationComplete() 
    { 
     machine.Fire(Trigger.RegistrationComplete); 
    } 

} 

Chúng ta có nên thực hiện tất cả các quy trình (gọi đến các dịch vụ) trong vòng móc OnEntry, hoặc thực hiện các quá trình ở bên ngoài sau khi chuyển đổi trạng thái đã được xác minh rằng nó là được phép diễn ra? Tôi tự hỏi làm thế nào để làm quản lý giao dịch nếu có.

Tôi đoán những gì tôi theo sau là một số hướng dẫn tốt nhất từ ​​những người đã triển khai một cái gì đó bằng cách sử dụng trạng thái không trạng thái và cách tiếp cận cấu trúc mã.

+0

Nhìn vào điều này một số chi tiết, tôi đang hướng tới sử dụng một nhà máy được tiêm vào các dịch vụ miền để xây dựng đối tượng dòng công việc và điều này có thể vượt qua trong các dịch vụ theo yêu cầu của đối tượng dòng công việc. – dandcg

+0

Vẫn đang xem xét một số hướng dẫn về cách tiếp cận tốt nhất khi sử dụng máy trạng thái. Giả sử tôi cần gọi một phương thức trên dịch vụ gửi email tồn tại trong suốt thời gian yêu cầu web. Nếu cuộc gọi này đi trong OnEntry hoặc trong phương thức công khai. Nếu nó trong OnEntry những gì sẽ xảy ra nếu có một vấn đề trong quá trình chuyển đổi? Một số hướng dẫn từ những người đã triển khai mã bằng cách sử dụng không quốc tịch và nơi họ đã đặt mã thực hiện sẽ được đánh giá cao. – dandcg

Trả lời

11

Trước khi giải quyết các cấu trúc bản thân một vài nhận xét:

  • OnEntry hành động chỉ được thực hiện nếu cò đã được phóng thành công.

  • Kích hoạt được kích hoạt không được phép ở trạng thái hiện tại sẽ ném một số InvalidOperationException. Cân nhắc việc ghi đè OnUnhandledTrigger nếu bạn không mong đợi một ngoại lệ (tôi đã phát hiện thấy rằng trình kích hoạt ghi nhật ký bị lỗi là một cách tiếp cận tốt để tìm các lỗ hổng trong logic).

Quy tắc của ngón tay cái cho OnEntry/OnExit cơ cấu là bất kỳ sự sáng tạo và logic sẽ được đặt OnEntry và bất kỳ yêu cầu dọn dẹp được thực hiện OnExit. Vì vậy, trong trường hợp của bạn, cho rằng bạn đang sử dụng phụ thuộc tiêm (và giả sử bạn không dùng quyền sở hữu của những người đó, nghĩa là ai đó sẽ quản lý vòng đời của họ), bạn có thể đặt tất cả logic của mình OnEntry.

Với ý nghĩ đó, cách mà máy trạng thái của bạn hiện được cấu trúc hoàn toàn ổn.

Một lưu ý cuối cùng, lưu ý rằng kích hoạt kích hoạt từ trong cùng một luồng đang tiến lên máy trạng thái và làm logic máy trạng thái có thể và sẽ dẫn đến ngoại lệ stackoverflow (xem here về cách giải quyết sự cố tự động trước).

+0

Xin chào Omni, cảm ơn vì điều này. điều gì sẽ xảy ra nếu sau đó lỗi xảy ra trong quá trình triển khai OnEntry - liệu trạng thái có còn thay đổi không? Ngoài ra, bạn sẽ thường sử dụng một nhà máy để tạo ra thể hiện dòng công việc?Điều này sẽ đối phó với new-ing dụ wf với trạng thái bắt đầu và đi qua trong các phụ thuộc theo yêu cầu của việc thực hiện? – dandcg

+0

Xin chào @dandcg. Quá trình chuyển đổi trạng thái xảy ra trước khi 'OnEntry' được xử lý, do đó, khi ngoại lệ được ném, trạng thái đã được thay đổi. Sau đó bạn phải quyết định nơi để xử lý các ngoại lệ. Hoặc là bên trong 'OnEntry' hoặc trong' machine.Fire (...) 'đã chuyển sang trạng thái ném ra ngoại lệ. Không có nhiều trong việc sử dụng một nhà máy để tạo ra 'AccountWf' tôi muốn nói. Một nhà máy sẽ hữu ích nếu phụ thuộc vào các tham số, bạn có các loại máy/cấu hình khác nhau. – Omni

+0

Lý do cho nhà máy là tôi không muốn tiêm bản thân dòng công việc? Nhưng tôi cho rằng điều này là ok. Bạn chơi nó như thế nào? – dandcg

Các vấn đề liên quan