首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通用仓库Loc

通用仓库Loc
EN

Stack Overflow用户
提问于 2015-08-29 15:35:06
回答 1查看 100关注 0票数 0

我正在学习实体框架( Entity ),并尝试使用worker模式的通用存储库。使用城堡、温莎,我将通过接口注入所有内容。

然而,工作单元属性InternetRepository是紧密耦合的:

代码语言:javascript
复制
public interface IUnitOfWork
{
    IGenericRepository<RecordInternetSpeed> InternetSpeedRepository { get; }
    void Save();
}

public class UnitOfWork :IUnitOfWork, IDisposable
{
    private bool disposed = false;
    private InternetSpeedEntities context = new InternetSpeedEntities();

    private IGenericRepository<RecordInternetSpeed> internetSpeedRepository;
    public IGenericRepository<RecordInternetSpeed> InternetSpeedRepository
    {
        get
        {
            if(this.internetSpeedRepository == null)
            {
                this.internetSpeedRepository = new GenericRepository<RecordInternetSpeed>(context);
            }
            return internetSpeedRepository;
        }
    }

    public void Save()
    {
        context.SaveChanges();
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                context.Dispose();
            }
        }
        this.disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

如何注入此属性以使用接口?下面进一步说明了如何调用IUnitOfWork

代码语言:javascript
复制
    private Timer timer;
    private ICalculateInternetSpeed internetSpeed;
    private IUnitOfWork unitOfWork;

    public MyRunner(ICalculateInternetSpeed internetSpeed, IUnitOfWork unitOfWork)
    {
        this.internetSpeed = internetSpeed;
        this.unitOfWork = unitOfWork;
    }

    public void Start()
    {
        timer = new Timer
                    {
                        //1000 (1 sec)
                        Interval = 5000,
                        Enabled = true
                    };

        timer.Elapsed += (TimerElapsed);
    }

   public void Stop()
   {

   }

   private void TimerElapsed(object sender, ElapsedEventArgs e)
   {
       try
       {
           timer.Enabled = false;
           //Kick off method to get the download speed
           var speed = internetSpeed.CalculateInternetDownloadSpeed();
           Logger.Logger.Info("Internet Speed calculated.");
           unitOfWork.InternetSpeedRepository.Insert(speed);
           unitOfWork.Save();
           Logger.Logger.Info(string.Format("Inserted record with ID {0} into the database.", speed.RecordId));
       }
       catch (Exception ex)
       {
           Logger.Logger.Error(ex.ToString());
       }
       finally
       {
           timer.Enabled = true;
       }
   }
}

然后在我的程序的主类中调用它:

代码语言:javascript
复制
private static void Main(string[] args)
    {
        container = new WindsorContainer(new XmlInterpreter());
        container.Install(FromAssembly.This());
        var runner = container.Resolve<IMyRunner>();

        HostFactory.Run(x =>
            {
                x.Service<IMyRunner>(s =>
                    {
                        s.SetServiceName(ServiceName);
                        s.ConstructUsing(c => runner);
                        s.WhenStarted(tc => tc.Start());
                        s.WhenStopped(tc =>
                            {
                                tc.Stop();
                                container.Release(runner);
                            });
                    });

                x.RunAsLocalSystem();
                x.SetDescription(ServiceDescription);
                x.SetDisplayName(ServiceDisplayName);
                x.SetServiceName(ServiceName);
                x.StartAutomatically();

            });
    }

我认为需要的最后一个代码片段是我的安装程序类:

代码语言:javascript
复制
public class Installer : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(Component.For<IMyRunner>().ImplementedBy<MyRunner>().LifeStyle.Transient,
                           Component.For<ICalculateInternetSpeed>().ImplementedBy<CalculateInternetSpeed>().LifeStyle.Transient,
                           Component.For<IUnitOfWork>().ImplementedBy<UnitOfWork>().LifeStyle.Transient,
                           Component.For<ISimpleWebClient>().ImplementedBy<SimpleWebClient>(),
                           Component.For<IConfig>().ImplementedBy<Config>(),
                           Component.For<IGenericRepository<RecordInternetSpeed>>().ImplementedBy<GenericRepository<RecordInternetSpeed>>());
    }
}

正如你所看到的,我试图在这里注入它,但不确定这是否有效。这是进行属性注入的正确方法吗?

EN

回答 1

Stack Overflow用户

发布于 2015-08-30 11:39:51

首先,确保注册InternetSpeedEntities

然后,要么在Unit构造函数中接受IGenericRepository<RecordInternetSpeed>作为参数并设置私有字段,要么将该属性转换为一个带有getter和setter的自动属性,而Castle将为您完成该工作。

然而,很少有其他注意事项:

  • 尝试习惯于通过约定注册组件(例如,container.Register( Classes.FromThisAssembly() .Pick().WithServiceDefaultInterfaces() ) );)那样的话,你就不用手动做任何事情了。
  • 注意你的部件的生活方式。如果您不指定一个-默认情况下它是一个单例。在容器被处理之前,这些是不会被处理的。或者,您可以将组件的生活方式绑定到父对象,键入对象图。

希望这有帮助,祝你好运!

-编辑-

作为一个示例,您的UnitOfWork可以如下所示:

代码语言:javascript
复制
public class UnitOfWork : IUnitOfWork, IDisposable
{
    public UnitOfWork(GenericRepository<RecordInternetSpeed> repository, InternetSpeedEntities context)
    {
        this.context = context;
        this.InternetSpeedRepository = repository;
    }

    private bool disposed = false;
    private InternetSpeedEntities context;

    public IGenericRepository<RecordInternetSpeed> InternetSpeedRepository { get; private set; }

    ...

} 

您的安装程序可能如下所示:

代码语言:javascript
复制
public class Installer : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(
            Classes.FromThisAssembly()
            .Pick().WithServiceDefaultInterfaces()
            .LifestyleTransient()
            );
    }
}  

存储库和上下文是UnitOfWork的依赖项。只要温莎知道如何创建它们,它就会在解决过程中将它们提供给构造函数。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32287730

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档