You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular与C# DLL API通信插件开发及DataService优化咨询

Great question! Let's walk through refining your Angular + Edge.js setup to make it more dynamic, maintainable, and user-friendly for button-triggered data fetching. First, let's address a couple of issues in your current DataService and then build out a robust solution.

Key Issues in Your Current Code

  • Template String Misuse: You're using ${type} inside single quotes ('), which won't interpolate the variables—you need backticks (`) for that.
  • Asynchronous Handling: The getData method uses a callback but doesn't properly return the result asynchronously. Right now, the return value won't work as expected because the callback runs after the method exits.
  • Hardcoded Path: The DLL path is hardcoded, which makes the code less portable and harder to maintain.

Step 1: Refactor the DataService for Async & Maintainability

Let's rewrite the service to use Promises (so we can leverage async/await in components) and add configuration for the DLL path:

import { Injectable } from '@angular/core';
import { environment } from '../environments/environment';

const edge = require('edge');

@Injectable({ providedIn: 'root' })
export class DataService {
  private readonly dllPath = environment.siemensDllPath;

  constructor() { }

  getData(type: string, method: string): Promise<any> {
    return new Promise((resolve, reject) => {
      try {
        const dataFetcher = edge.func({
          assemblyFile: this.dllPath,
          typeName: `CC.CommonInterfaces.${type}`,
          methodName: `${method}`
        });

        dataFetcher(null, (error: any, result: any) => {
          if (error) {
            console.error('DLL call failed:', error);
            reject(new Error(`Failed to call method ${method} on type ${type}: ${error.message}`));
          } else {
            console.log('DLL call succeeded:', result);
            resolve(result);
          }
        });
      } catch (setupError) {
        reject(new Error(`Failed to initialize Edge.js function: ${setupError.message}`));
      }
    });
  }
}

Add the DLL path to your environment.ts (and environment.prod.ts for production):

export const environment = {
  production: false,
  siemensDllPath: 'C:\\Program Files\\Common Files\\Siemens\\Automation\\Simatic OAM\\bin\\CC.CommonInterfaces.dll'
};

Step 2: Build a Dynamic Component with Button Trigger

Create a component that lets users input (or select) the type and method, triggers the data fetch on button click, and shows loading/error states:

Component Template (data-fetcher.component.html)

<div class="data-fetch-container">
  <div class="input-group">
    <label>Type Name:</label>
    <input 
      [(ngModel)]="selectedType" 
      placeholder="e.g. MyDataInterface"
      class="input-field"
    >
  </div>
  <div class="input-group">
    <label>Method Name:</label>
    <input 
      [(ngModel)]="selectedMethod" 
      placeholder="e.g. GetLatestData"
      class="input-field"
    >
  </div>

  <button 
    (click)="handleFetchClick()" 
    [disabled]="isLoading || !isInputValid()"
    class="fetch-btn"
  >
    {{ isLoading ? 'Fetching...' : 'Get Data' }}
  </button>

  <div *ngIf="errorMessage" class="error-alert">
    {{ errorMessage }}
  </div>

  <div *ngIf="fetchedData" class="result-section">
    <h3>Result:</h3>
    <pre>{{ fetchedData | json }}</pre>
  </div>
</div>

Component Class (data-fetcher.component.ts)

import { Component } from '@angular/core';
import { DataService } from './data.service';

@Component({
  selector: 'app-data-fetcher',
  templateUrl: './data-fetcher.component.html',
  styleUrls: ['./data-fetcher.component.css']
})
export class DataFetcherComponent {
  selectedType = '';
  selectedMethod = '';
  fetchedData: any;
  errorMessage = '';
  isLoading = false;

  constructor(private dataService: DataService) {}

  isInputValid(): boolean {
    return !!this.selectedType.trim() && !!this.selectedMethod.trim();
  }

  async handleFetchClick(): Promise<void> {
    if (!this.isInputValid()) return;

    this.isLoading = true;
    this.errorMessage = '';
    this.fetchedData = null;

    try {
      this.fetchedData = await this.dataService.getData(this.selectedType, this.selectedMethod);
    } catch (err) {
      this.errorMessage = (err as Error).message;
    } finally {
      this.isLoading = false;
    }
  }
}

Step 3: Enhance Dynamicity & Type Safety

To make the code even more robust and dynamic:

  • Add Enums for Valid Types/Methods: If you know the allowed type and method values upfront, create enums to avoid typos:

    export enum SiemensDataTypes {
      AssetProvider = 'AssetProvider',
      StatusMonitor = 'StatusMonitor'
    }
    
    export enum SiemensDataMethods {
      GetAllAssets = 'GetAllAssets',
      GetCurrentStatus = 'GetCurrentStatus'
    }
    

    Then replace the input fields with dropdowns using these enums for selection.

  • Add Caching: If some data doesn't change frequently, add a cache in DataService to avoid redundant DLL calls:

    private cache = new Map<string, any>();
    
    getData(type: string, method: string): Promise<any> {
      const cacheKey = `${type}-${method}`;
      if (this.cache.has(cacheKey)) {
        return Promise.resolve(this.cache.get(cacheKey));
      }
    
      // ... existing Promise logic ...
      // After resolving, add to cache:
      this.cache.set(cacheKey, result);
    }
    

Critical Environment Note

Remember: Edge.js only works in a Node.js environment. This means your Angular app must be:

  • An Electron application (runs in a Node.js + Chromium context)
  • An Angular Universal app (server-side rendering, where the backend runs Node.js)
  • A Node.js-based Angular app (not a pure browser-only app—browser JS can't directly call Windows DLLs)

If you need a browser-only solution, you'll need to build a Node.js backend API that calls the DLL, then have your Angular app hit that API via HTTP.


内容的提问来源于stack exchange,提问作者Moorky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 08:42:43