Tag: SoftwareEngineering

  • If-Else vs Ternary Operator in C#: When Should You Use Each?

    If-Else vs Ternary Operator in C#: When Should You Use Each?

    As C# developers, we often need to make decisions in our code.

    Two common ways to do this are:

    • if-else
    • The ternary operator (?:)

    Both achieve the same goal, but choosing the right one can make your code either easier—or harder—to read.

    Let’s explore when each approach is the better choice.

    Using if-else

    The if-else statement is ideal when the logic is more than a simple decision.

    Example:

    if (age >= 18)
    {
        category = "Adult";
    }
    else
    {
        category = "Minor";
    }
    

    This style is easy to understand, especially when additional conditions or multiple statements are involved.

    When to Use if-else

    Use if-else when:

    • You have multiple statements to execute.
    • The logic is complex.
    • You need nested conditions.
    • Readability is more important than brevity.

    Using the Ternary Operator

    The ternary operator provides a shorter way to assign a value based on a condition.

    Syntax:

    condition ? valueIfTrue : valueIfFalse;
    

    Example:

    string category = age >= 18 ? "Adult" : "Minor";
    

    This is concise, expressive, and easy to read.


    A Good Use Case

    The ternary operator works well for simple value assignments.

    string status = isActive ? "Active" : "Inactive";
    

    Simple.

    Readable.

    No unnecessary lines of code.


    A Bad Use Case

    Avoid chaining multiple ternary operators.

    string result = score >= 80
        ? "Excellent"
        : score >= 60
            ? "Good"
            : score >= 40
                ? "Average"
                : "Fail";
    

    Although valid, this quickly becomes difficult to read and maintain.

    An if-else block communicates the same logic much more clearly.


    Comparison

    ScenarioRecommended
    Simple value assignment✅ Ternary Operator
    Multiple statements✅ If-Else
    Complex business logic✅ If-Else
    Nested conditions✅ If-Else
    Short, readable conditions✅ Ternary Operator

    Best Practices

    ✔ Use the ternary operator only for simple expressions.

    ✔ Prefer if-else for complex decision-making.

    ✔ Avoid deeply nested ternary operators.

    ✔ Prioritize readability over writing fewer lines of code.

    Remember:

    Code is read far more often than it is written.


    Final Thoughts

    The ternary operator is a great tool—but like any tool, it should be used appropriately.

    If it makes your code clearer, use it.

    If it makes someone stop and think, an if-else statement is probably the better choice.

    The goal isn’t to write the shortest code—it’s to write code that’s easy for your future self and your teammates to understand.

  • What If a User Uploads a Dangerous File to Your Server? Here’s How to Prevent It.

    What If a User Uploads a Dangerous File to Your Server? Here’s How to Prevent It.

    File upload is one of the most common features in web applications—but it’s also one of the most targeted by attackers.

    Imagine a user uploads a file named:

    invoice.pdf.exe
    

    Or renames a malicious executable to:

    resume.pdf
    

    If your application trusts only the file name or extension, you could expose your server to serious security risks.

    A secure file upload system should never rely on a single validation step.

    1. Validate the File Extension

    Allow only the file types your application actually needs.

    Example:

    • ✅ .pdf
    • ✅ .jpg
    • ✅ .png
    • ✅ .docx

    Reject everything else.

    Remember: This is your first line of defense—not your only one.


    2. Verify the MIME Type

    Don’t trust the extension alone.

    Check the file’s MIME type sent by the client.

    For example:

    • application/pdf
    • image/jpeg
    • image/png

    Keep in mind that MIME types can also be spoofed, so continue with additional checks.


    3. Validate the File Signature (Magic Numbers)

    The most reliable validation is checking the file’s binary signature.

    For example:

    • PDF → %PDF
    • PNG → 89 50 4E 47
    • JPEG → FF D8 FF

    If the file signature doesn’t match the expected format, reject the upload.


    4. Limit File Size

    Prevent attackers from uploading extremely large files.

    Example:

    • Images: 5 MB
    • Documents: 20 MB

    This reduces the risk of storage abuse and denial-of-service attacks.


    5. Rename Uploaded Files

    Never store files using the original filename.

    Instead, generate a unique name.

    Example:

    3b8b2d1d-ef7d-4db2-8a8c-0f5d91a0f4a7.pdf
    

    This avoids filename collisions and reduces information disclosure.


    6. Store Files Outside the Web Root

    Avoid storing uploaded files in directories that can execute code.

    Instead:

    • Store files outside the web root.
    • Serve them through a controller or API after authorization.

    This prevents direct execution of uploaded files.


    7. Scan for Malware

    Integrate an antivirus solution to scan uploaded files before making them available.

    This is especially important for systems that accept documents from external users.


    8. Restrict File Permissions

    Uploaded files should never have execute permissions.

    Grant only the minimum permissions required to read or write the file.


    9. Authorize Access

    Not every uploaded file should be publicly accessible.

    Always verify that the requesting user has permission to download or view the file.


    10. Log Upload Activity

    Record important details such as:

    • User ID
    • IP address
    • File name
    • File size
    • Upload time
    • Validation failures

    Logs help detect suspicious activity and support incident investigations.


    Final Thoughts

    Secure file uploads are about defense in depth.

    Don’t rely on a single validation.

    A robust upload pipeline should include:

    • Extension validation
    • MIME type verification
    • File signature checks
    • Size limits
    • Malware scanning
    • Secure storage
    • Proper authorization

    Security isn’t a single feature—it’s a combination of small decisions that work together to protect your application.

  • User বারবার Send Button চাপল, আর Customer-এর টাকা দুইবার কেটে গেল! এটা কীভাবে প্রতিরোধ করবেন?

    User বারবার Send Button চাপল, আর Customer-এর টাকা দুইবার কেটে গেল! এটা কীভাবে প্রতিরোধ করবেন?

    ধরুন, আপনি একটি Payment API তৈরি করেছেন।

    একজন User “Pay Now” বাটনে চাপ দিলেন।

    কিন্তু Server একটু ধীর (Slow)।

    User ভাবলেন,

    “হয়তো Click হয়নি!”

    তিনি আবার Button চাপলেন।

    তারপর আবার।

    কয়েক সেকেন্ড পরে…

    Customer Support থেকে ফোন—

    “একই Payment-এর জন্য Customer-এর টাকা দুইবার কেটে গেছে!”

    এখন প্রশ্ন হলো—

    সমস্যাটা User-এর, নাকি System-এর?

    আমার মতে, System-এর।

    কারণ একটি ভালো Payment System কখনোই একই Payment একাধিকবার Process করবে না।


    প্রথম প্রতিরক্ষা: Frontend

    Frontend থেকেই Duplicate Request কমানো যায়।

    যেমন—

    • Button Click করার পর Disable করে দেওয়া।
    • Loading Spinner দেখানো।
    • Request Complete না হওয়া পর্যন্ত দ্বিতীয় Click Block করা।

    এতে অনেক Duplicate Request শুরুতেই বন্ধ হয়ে যায়।

    কিন্তু…

    শুধু Frontend-এর উপর নির্ভর করা যাবে না।

    কারণ—

    • User Page Refresh করতে পারে।
    • Network Retry হতে পারে।
    • Mobile App একই Request আবার পাঠাতে পারে।
    • কোনো Bot Request পাঠাতে পারে।

    তাই আসল নিরাপত্তা Backend-এ থাকতে হবে।


    দ্বিতীয় প্রতিরক্ষা: Idempotency Key

    প্রতিটি Payment Request-এর সাথে একটি Unique Id পাঠানো হয়।

    যেমন—

    Idempotency-Key: 7f4c9d...
    

    যদি একই Key আবার আসে,

    Server নতুন Payment Process করবে না।

    আগের Result-ই Return করবে।


    তৃতীয় প্রতিরক্ষা: Database Constraint

    Database-এ এমনভাবে Design করুন,

    যাতে একই Transaction Reference দুইবার Insert-ই করা না যায়।

    যেমন—

    • PaymentReference
    • OrderId
    • TransactionId

    এসবের উপর Unique Constraint থাকতে পারে।

    Database অনেক সময় শেষ নিরাপত্তা দেয়।


    চতুর্থ প্রতিরক্ষা: Transaction

    Payment-এর গুরুত্বপূর্ণ Operation-গুলো Transaction-এর মধ্যে করুন।

    যাতে মাঝপথে কোনো সমস্যা হলে Partial Data Save না হয়।


    পঞ্চম প্রতিরক্ষা: Distributed Lock (যেখানে প্রয়োজন)

    যদি Multiple Server একই Payment Process করতে পারে,

    তাহলে Redis Distributed Lock-এর মতো সমাধান ব্যবহার করা যেতে পারে।

    এতে একই সময়ে একটি Payment শুধুমাত্র একটি Server Process করবে।


    সবচেয়ে গুরুত্বপূর্ণ শিক্ষা

    একজন User একই Request একাধিকবার পাঠাতে পারেন।

    Network একই Request Retry করতে পারে।

    Gateway একই Callback আবার পাঠাতে পারে।

    এসবই স্বাভাবিক।

    অস্বাভাবিক হলো—

    System সেই Request-গুলোকে নতুন Payment হিসেবে ধরে আবার টাকা কেটে ফেলছে।

    একটি ভালো Payment System-এর লক্ষ্য হওয়া উচিত—

    “One business operation = One successful payment.”

    যতবার Request আসুক না কেন।

  • ম্যানেজার হঠাৎ বললেন, “এই Project-এর Estimation করে দেন!” — তখন কী করবেন?

    ম্যানেজার হঠাৎ বললেন, “এই Project-এর Estimation করে দেন!” — তখন কী করবেন?

    সকালের Stand-up Meeting শেষ।

    হঠাৎ ম্যানেজার বললেন,

    “Faiz, এই নতুন Project-এর একটা Estimation আজকেই লাগবে।”

    প্রথম প্রতিক্রিয়া কী হবে?

    অনেকেই তাড়াহুড়ো করে একটা সংখ্যা বলে দেন—

    “মনে হয়… ২ সপ্তাহ লাগবে।”

    কিন্তু একজন অভিজ্ঞ Software Engineer জানেন,

    Estimation মানে Guess করা নয়।

    Estimation মানে হলো, বর্তমান তথ্যের ভিত্তিতে একটি যৌক্তিক পূর্বাভাস (Forecast)।


    আমি কীভাবে শুরু করি?

    প্রথমেই আমি একটি প্রশ্ন করি—

    Requirement কি পুরোপুরি পরিষ্কার?

    যদি Requirement পরিষ্কার না হয়, তাহলে কোনো Estimation-ই নির্ভুল হবে না।


    এরপর Project-টাকে ছোট ছোট অংশে ভাগ করি

    একটি বড় Feature-এর Estimation করা কঠিন।

    কিন্তু যদি এটিকে ভাগ করি—

    • Authentication
    • Database Design
    • API Development
    • Frontend Integration
    • Unit Testing
    • Deployment

    তাহলে Estimation অনেক বাস্তবসম্মত হয়।


    Unknown বিষয়গুলো আলাদা করি

    সব Project-এই কিছু Unknown থাকে।

    যেমন—

    • Third-party API Integration
    • নতুন Technology
    • Client-এর পরিবর্তিত Requirement

    এসব ঝুঁকি (Risk) আগে থেকেই চিহ্নিত করলে Estimation আরও বাস্তবসম্মত হয়।


    Buffer রাখতে ভুলবেন না

    একটি Project কখনোই শুধুমাত্র Coding নয়।

    এর সাথে থাকে—

    • Code Review
    • Bug Fix
    • Testing
    • Meeting
    • Deployment
    • Production Support

    শুধু Coding Time ধরে Estimation করলে প্রায়ই Deadline মিস হয়।


    সবচেয়ে বড় ভুল

    অনেক সময় আমরা Pressure-এর কারণে বলি—

    “হ্যাঁ, হয়ে যাবে।”

    কিন্তু বাস্তবে Requirement না বুঝে দেওয়া Estimation পুরো Team-এর জন্য সমস্যার কারণ হতে পারে।

    একজন Professional Engineer প্রয়োজনে বলেন—

    “আমি Requirement Review করে আজ বিকেলের মধ্যে একটি বাস্তবসম্মত Estimation জানাচ্ছি।”

    এটা দুর্বলতা নয়, বরং Professionalism।


    আমার শেখা একটি বিষয়

    বছরের পর বছর কাজ করে একটি বিষয় বুঝেছি—

    ভুল Estimation দেওয়ার চেয়ে, একটু সময় নিয়ে সঠিক Estimation দেওয়া অনেক ভালো।

    কারণ Deadline মিস করলে শুধু Project নয়, Team-এর বিশ্বাসও ক্ষতিগ্রস্ত হয়।

    শেষ কথা

    Estimation কোনো প্রতিশ্রুতি (Promise) নয়।

    এটি হলো একটি Forecast, যা বর্তমান তথ্যের উপর ভিত্তি করে তৈরি হয়।

    আর একজন ভালো Software Engineer-এর কাজ শুধু দ্রুত উত্তর দেওয়া নয়, বরং তথ্যভিত্তিক এবং বাস্তবসম্মত উত্তর দেওয়া।

  • 𝗔𝗦𝗣.𝗡𝗘𝗧 𝗖𝗼𝗿𝗲-এ 𝗮𝗽𝗽.𝗨𝘀𝗲𝗦𝘄𝗮𝗴𝗴𝗲𝗿() এবং 𝗮𝗽𝗽.𝗨𝘀𝗲𝗦𝘄𝗮𝗴𝗴𝗲𝗿𝗨𝗜() কেন ব্যবহার করা হয়?

    𝗔𝗦𝗣.𝗡𝗘𝗧 𝗖𝗼𝗿𝗲-এ 𝗮𝗽𝗽.𝗨𝘀𝗲𝗦𝘄𝗮𝗴𝗴𝗲𝗿() এবং 𝗮𝗽𝗽.𝗨𝘀𝗲𝗦𝘄𝗮𝗴𝗴𝗲𝗿𝗨𝗜() কেন ব্যবহার করা হয়?

    ধরুন, আপনি একটি নতুন Web API তৈরি করেছেন।

    সব endpoint ঠিকমতো কাজ করছে।

    আপনি Postman দিয়ে test করছেন।

    কিন্তু হঠাৎ আপনার টিমের একজন Developer এসে বলল,

    “API-এর documentation কোথায়?”

    আপনি বললেন,

    “Postman Collection আছে।”

    সে আবার বলল,

    “নতুন Developer join করলে কি Postman Collection দিয়েই সব বুঝতে হবে?”

    এখানেই Swagger-এর প্রয়োজনীয়তা শুরু।

    Swagger আসলে কী?

    Swagger হলো এমন একটি tool যা আপনার Web API-এর documentation automatically তৈরি করে।

    অর্থাৎ, আপনার API-তে কী কী endpoint আছে,

    • কোন URL
    • কোন HTTP Method (GET, POST, PUT, DELETE)
    • কী parameter লাগবে
    • কী response আসবে

    সবকিছু সুন্দরভাবে একটি UI-তে দেখিয়ে দেয়।


    তাহলে app.UseSwagger() কী করে?

    app.UseSwagger();
    

    এই লাইনটি Swagger-এর JSON documentation generate করে।

    যেমন:

    /swagger/v1/swagger.json
    

    এই JSON file-এর মধ্যেই আপনার পুরো API-এর description থাকে।

    অর্থাৎ এটি UI নয়।

    এটি শুধুমাত্র API-এর metadata তৈরি করে।


    তাহলে app.UseSwaggerUI() কী করে?

    app.UseSwaggerUI();
    

    এই লাইনটি সেই JSON file-কে একটি সুন্দর Web UI-তে দেখায়।

    ফলে Browser থেকে আপনি দেখতে পারেন—

    ✅ সব Endpoint

    ✅ Request Body

    ✅ Parameters

    ✅ Response

    ✅ এমনকি Browser থেকেই API Call করতে পারেন।


    বাস্তব উদাহরণ

    ধরুন আপনি একটি Food Delivery API বানিয়েছেন।

    Swagger UI খুললে দেখতে পারবেন—

    GET     /api/restaurants
    
    GET     /api/restaurants/{id}
    
    POST    /api/orders
    
    PUT     /api/orders/{id}
    
    DELETE  /api/orders/{id}
    

    প্রতিটি endpoint-এ ক্লিক করে আপনি Request পাঠাতে পারবেন।

    Postman খুলারও দরকার হবে না।


    যদি শুধু UseSwagger() লিখেন?

    তাহলে JSON তৈরি হবে।

    কিন্তু Browser-এ সুন্দর UI পাবেন না।


    যদি শুধু UseSwaggerUI() লিখেন?

    Swagger UI দেখানোর জন্য JSON দরকার।

    UseSwagger() না থাকলে UI কাজ করতে পারবে না।

    অর্থাৎ—

    দুইটি middleware একে অপরের উপর নির্ভরশীল।


    Development Environment-এ কেন বেশি ব্যবহার করা হয়?

    অনেক Project-এ আপনি এমন Code দেখবেন—

    if (app.Environment.IsDevelopment())
    {
        app.UseSwagger();
        app.UseSwaggerUI();
    }
    

    কারণ Production Environment-এ অনেক সময় API documentation public রাখা হয় না।

    Security-এর কারণেও অনেক প্রতিষ্ঠান Production-এ Swagger disable করে রাখে।


    আমার পরামর্শ

    Swagger শুধু API দেখানোর জন্য নয়।

    এটি Team Collaboration অনেক সহজ করে।

    নতুন Developer onboarding, Frontend integration, QA testing—সব ক্ষেত্রেই Swagger অসাধারণ একটি tool।

    আমার মতে, ASP.NET Core শিখতে গেলে Swagger বোঝা বাধ্যতামূলক।

    কারণ এটি শুধু documentation নয়, এটি আপনার API-এর “Interactive User Manual”।

  • 𝗪𝗵𝗮𝘁’𝘀 𝗡𝗲𝘄 𝗶𝗻 𝗖# 𝟭𝟰: 𝗠𝗼𝗱𝗲𝗿𝗻 𝗙𝗲𝗮𝘁𝘂𝗿𝗲𝘀 𝗧𝗵𝗮𝘁 𝗠𝗮𝗸𝗲 𝗬𝗼𝘂𝗿 𝗖𝗼𝗱𝗲 𝗖𝗹𝗲𝗮𝗻𝗲𝗿 𝗮𝗻𝗱 𝗠𝗼𝗿𝗲 𝗘𝘅𝗽𝗿𝗲𝘀𝘀𝗶𝘃𝗲

    𝗪𝗵𝗮𝘁’𝘀 𝗡𝗲𝘄 𝗶𝗻 𝗖# 𝟭𝟰: 𝗠𝗼𝗱𝗲𝗿𝗻 𝗙𝗲𝗮𝘁𝘂𝗿𝗲𝘀 𝗧𝗵𝗮𝘁 𝗠𝗮𝗸𝗲 𝗬𝗼𝘂𝗿 𝗖𝗼𝗱𝗲 𝗖𝗹𝗲𝗮𝗻𝗲𝗿 𝗮𝗻𝗱 𝗠𝗼𝗿𝗲 𝗘𝘅𝗽𝗿𝗲𝘀𝘀𝗶𝘃𝗲

    C# continues to evolve with every release, focusing on making developers more productive while keeping code clean, readable, and maintainable.

    C# 14 introduces several improvements that help developers write simpler and more expressive code.

    Here are some notable features:

    1. Extension Members

    C# 14 expands extension methods with a more powerful concept called extension members.

    Previously, extension methods allowed adding methods to existing types without modifying them.

    Now, extension members allow developers to add more than just methods, including properties and other members.

    This makes APIs easier to design and improves code organization.


    2. Null-Conditional Assignment

    C# 14 improves null handling by allowing assignments through null-conditional operators.

    Before:

    if (customer != null)
    {
        customer.Name = "Faiz";
    }
    

    With C# 14:

    customer?.Name = "Faiz";
    

    This reduces unnecessary null checks and improves readability.


    3. Field Keyword

    C# 14 introduces the field keyword, making property implementations cleaner.

    Before:

    private string _name;
    
    public string Name
    {
        get => _name;
        set => _name = value;
    }
    

    With C# 14:

    public string Name
    {
        get;
        set => field = value;
    }
    

    This reduces boilerplate code while keeping control over property behavior.


    4. More Flexible Method Overloads

    C# 14 improves overload resolution and allows developers to create APIs with better flexibility and fewer workarounds.

    This helps when designing libraries and reusable components.


    5. Improved Developer Experience

    Besides new language features, C# 14 continues improving:

    ✅ Code readability
    ✅ Developer productivity
    ✅ Performance opportunities
    ✅ Modern application development patterns


    The goal of every C# update is not just adding features.

    The real goal is helping developers write code that is:

    ✔ Easier to understand
    ✔ Easier to maintain
    ✔ Less error-prone
    ✔ More aligned with modern software practices

    As .NET developers, staying updated with language evolution helps us make better technical decisions.

    💬 Which C# 14 feature are you most excited to use in your projects?

    ♻️ If you found this helpful, feel free to repost and share it with your network.

    Follow Engineer Faiz for more insights on software engineering and technology.

    #csharp #dotnet #softwareengineering #backenddevelopment #programming

  • Control Makes People Behave. Autonomy Makes People Engage.

    Control Makes People Behave. Autonomy Makes People Engage.

    A team can follow rules and still lack ownership.

    Why?

    Because compliance and commitment are not the same thing.

    Control can create short-term results:

    ✅ People follow instructions

    ✅ Tasks are completed on time

    ✅ Processes are maintained

    But excessive control can also create:

    ❌ Fear of making decisions

    ❌ Less creativity

    ❌ Waiting for approval instead of taking ownership

    ❌ A “just do what I was told” mindset

    Autonomy creates a different environment.

    When people have trust and freedom to make decisions:

    ✅ They think beyond their assigned tasks

    ✅ They take responsibility for outcomes

    ✅ They bring new ideas

    ✅ They feel connected to the team’s success

    For example:

    A manager says:

    “Complete this task exactly as I described.”

    The employee focuses on finishing the task.

    A better approach:

    “Here is the goal. Choose the best way to achieve it.”

    The employee starts thinking like an owner.

    Good leadership is not about controlling every action.

    It is about providing:

    • Clear expectations
    • The right direction
    • Necessary support
    • Freedom to execute

    The goal is not to create people who only follow instructions.

    The goal is to build people who can think, decide, and contribute.

    💡 Great teams are not built on control alone.

    They are built on trust with accountability.

    👇 What creates better teams in your experience?

    More control or more autonomy?

    ♻️ If you found this helpful, feel free to repost and share it with your network.

    👉 Follow Faiz Ahmed Rasel for more .NET tips, tutorials, and deep dives.

    #Leadership #TeamManagement #ProfessionalGrowth #SoftwareEngineering #CareerDevelopment